Instead of silent acceptance of unsupported requested configuration
for PWM period and setting the boundary supported value, return
-ERANGE to a caller.
Duty period value equal to 0 or period is still accepted to allow
configuration by PWM sysfs interface, when it is set to 0 by default.
For reference this is a list of restrictions on period_ns == 1/freq:
| PWM parent clock | parent clock divisor | max freq | min freq |
+------------------+----------------------+----------+----------+
| HCLK == 13 MHz | 1 (min) | 50.7 KHz | 198.3 Hz |
| HCLK == 13 MHz | 15 (max) | 3.38 KHz | 13.22 Hz |
| RTC == 32.7 KHz | 1 (min) | 128 Hz | 0.5 Hz |
| RTC == 32.7 KHz | 15 (max) | 8.533 Hz | 0.033 Hz |
Note that PWM sysfs interface does not support setting of period more
than NSEC_PER_SEC / MAX_INT32 ~ 2 seconds, however this PWM controller
supports a period up to 30 seconds.
Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
The change fixes a problem, if duty_ns is too small in comparison
to period_ns (as a valid corner case duty_ns is 0 ns), then due to
PWM_DUTY() macro applied on a value the result is overflowed over 8
bits, and instead of the highest bitfield duty cycle value 0xff the
invalid duty cycle bitfield value 0x00 is written.
For reference the LPC32xx spec defines PWMx_DUTY bitfield description
is this way and it seems to be correct:
[Low]/[High] = [PWM_DUTY]/[256-PWM_DUTY], where 0 < PWM_DUTY <= 255.
In addition according to my oscilloscope measurements LPC32xx PWM is
"tristate" in sense that it produces a wave with floating min/max
voltage levels for different duty cycle values, for corner cases:
PWM_DUTY == 0x01 => signal is in range from -1.05v to 0v
....
PWM_DUTY == 0x80 => signal is in range from -0.75v to +0.75v
....
PWM_DUTY == 0xff => signal is in range from 0v to +1.05v
PWM_DUTY == 0x00 => signal is around 0v, PWM is off
Due to this peculiarity on very long period ranges (less than 1KHz)
and odd pre-divider values PWM generated wave does not remind a
clock shape signal, but rather a heartbit shape signal with positive
and negative peaks, so I would recommend to use high-speed HCLK clock
as a PWM parent clock and avoid using RTC clock as a parent.
The change corrects PWM output in corner cases and prevents any
possible overflows in calculation of values for PWM_DUTY and
PWM_RELOADV bitfields, thus helper macro definitions may be removed.
Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
As a preparatory change for switching LPC32xx mach support to common
clock framework fix clk_enable/clk_disable calls without matching
clk_prepare/clk_unprepare.
The driver can not be used on a platform with common clock framework
until clk_prepare/clk_unprepare calls are added, otherwise clk_enable
calls will fail and a WARN is generated:
# echo 1 > /sys/bus/platform/drivers/lpc32xx-pwm/4005c000.pwm/pwm/pwmchip0/pwm0/enable
------------[ cut here ]------------
WARNING: CPU: 0 PID: 701 at drivers/clk/clk.c:727 clk_core_enable+0x2c/0xa4()
Modules linked in: sc16is7xx
CPU: 0 PID: 701 Comm: sh Tainted: G W 4.3.0-rc2+ #171
Hardware name: LPC32XX SoC (Flattened Device Tree)
Backtrace:
[<>] (dump_backtrace) from [<>] (show_stack+0x18/0x1c)
[<>] (show_stack) from [<>] (dump_stack+0x20/0x28)
[<>] (dump_stack) from [<>] (warn_slowpath_common+0x90/0xb8)
[<>] (warn_slowpath_common) from [<>] (warn_slowpath_null+0x24/0x2c)
[<>] (warn_slowpath_null) from [<>] (clk_core_enable+0x2c/0xa4)
[<>] (clk_core_enable) from [<>] (clk_enable+0x24/0x38)
[<>] (clk_enable) from [<>] (lpc32xx_pwm_enable+0x1c/0x40)
[<>] (lpc32xx_pwm_enable) from [<>] (pwm_enable+0x48/0x5c)
[<>] (pwm_enable) from [<>] (pwm_enable_store+0x5c/0x78)
[<>] (pwm_enable_store) from [<>] (dev_attr_store+0x20/0x2c)
[<>] (dev_attr_store) from [<>] (sysfs_kf_write+0x44/0x50)
[<>] (sysfs_kf_write) from [<>] (kernfs_fop_write+0x134/0x194)
[<>] (kernfs_fop_write) from [<>] (__vfs_write+0x34/0xdc)
[<>] (__vfs_write) from [<>] (vfs_write+0xb8/0x140)
[<>] (vfs_write) from [<>] (SyS_write+0x50/0x90)
[<>] (SyS_write) from [<>] (ret_fast_syscall+0x0/0x38)
Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
LPC32xx SoC has two independent PWM controllers, they have different
clock parents, clock gates and even slightly different controls, and
each of these two PWM controllers has one output channel. Due to
almost similar controls arranged in a row it is incorrectly set that
there is one PWM controller with two channels, fix this problem, which
at the moment prevents separate configuration of different clock
parents and gates for both PWM controllers.
The change makes previous PWM device node description incompatible
with this update.
Signed-off-by: Vladimir Zapolskiy <vz@mleia.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
The data structure of_match_ptr() protects is always compiled in.
Hence of_match_ptr() is not needed.
Signed-off-by: Sachin Kamat <sachin.kamat@linaro.org>
Cc: Alexandre Pereira da Silva <aletes.xgr@gmail.com>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
Remove unneeded error handling on the result of a call to
platform_get_resource when the value is passed to devm_ioremap_resource.
Move the call to platform_get_resource adjacent to the call to
devm_ioremap_resource to make the connection between them more clear.
A simplified version of the semantic patch that makes this change is as
follows: (http://coccinelle.lip6.fr/)
// <smpl>
@@
expression pdev,res,n,e,e1;
expression ret != 0;
identifier l;
@@
- res = platform_get_resource(pdev, IORESOURCE_MEM, n);
... when != res
- if (res == NULL) { ... \(goto l;\|return ret;\) }
... when != res
+ res = platform_get_resource(pdev, IORESOURCE_MEM, n);
e = devm_ioremap_resource(e1, res);
// </smpl>
Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
Some drivers don't set the .owner fields of the struct device_driver or
struct pwm_ops, which causes the module usage count to become wrong.
Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
lpc32xx_pwm_config() is supposed to set duty_ns and period_ns,
it should not change PWM_ENABLE bit.
Signed-off-by: Axel Lin <axel.lin@ingics.com>
Tested-by: Roland Stigge <stigge@antcom.de>
Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
According to the LPC32x0 User Manual [1]:
For both PWM1 and PWM2 Control Registers:
BIT 31:
This bit gates the PWM_CLK signal and enables the external output pin
to the PWM_PIN_STATE logical level.
0 = PWM disabled. (Default)
1 = PWM enabled
So in lpc32xx_pwm_enable(), we should set PWM_ENABLE bit.
In lpc32xx_pwm_disable(), we should just clear PWM_ENABLE bit rather than
write 0 to the register which will also clear PWMx_RELOADV and PWMx_DUTY bits.
[1] http://www.nxp.com/documents/user_manual/UM10326.pdf
Signed-off-by: Axel Lin <axel.lin@ingics.com>
Tested-by: Roland Stigge <stigge@antcom.de>
Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
A few drivers already annotate this properly. Make the same change for
all other OF supporting drivers.
Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
Acked-by: Shawn Guo <shawn.guo@linaro.org>
Acked-by: Alexandre Pereira da Silva <aletes.xgr@gmail.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Convert all uses of devm_request_and_ioremap() to the newly introduced
devm_ioremap_resource() which provides more consistent error handling.
Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
A new driver has been added for the SPEAr platform and the TWL4030/6030
driver has been replaced by two drivers that control the regular PWMs
and the PWM driven LEDs provided by the chips.
The vt8500, tiecap, tiehrpwm, i.MX, LPC32xx and Samsung drivers have all
been improved and the device tree bindings now support the PWM signal
polarity.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.19 (GNU/Linux)
iQIcBAABAgAGBQJQ0XF+AAoJEN0jrNd/PrOhk5IP/RxjjfVM8z7i0xc6ykNRyv/3
y8jRh1miwPXeamLdW07vF2NILBtDBmZ8TUbfAMt1esf25UST79Rgol/ia+QlBb3q
w/pCDVGwlOW+2qUd34Nlb+CyKXRROIbPcFy29RZn+Z29qdkWn4LVS0nZ0UJPSPel
80P6qxkrFGG8eKsYKB7InA0g4Ds0neWRJAoYsVp5jzyOPFpUILPdaptX+iSEk1v3
VvkIx8eTDPZO9aqn8qL6bcE0g0AneF+dJ4qzLiswlsPMxsFIoVysw6n2JuEyy+FD
x0Ml86Zl4SiNzZa4Pwa1250MwFT3cvnjWbAdLb2CGJVMV/uGU6nuyfXV0Aa1XtjQ
C0k8LNshgiID8/m1/H3+/aUy9Cx/hj1KM4jchrwkCphlBiAEEryKjTPJXDwfjuBI
s5NP4rUwfNVSQT66RaNVZ7atOKyeVu+hwAKO0h6PHOsD1GwhsT+b51/YmWXmb2E5
OgLLOOHVFORfxCrsXRhWcHydMzfplOtfZ4smr4WG0hKUVn2Zp1DK1zDE2rCBB4X1
ZMas4OO9uDRY9IDXZUZUtXcDPDppI6Zx3YeE1/MWzmjWqzyEYFf5OXBbakPr40Rq
lKEwYPNf5yiqIURfFZiGDk61mrwA0Vi3i8vYfTFq1zyX9u8KbXeY8g7AhcyC1qsM
YhfCmJZ0njopu8oENMgn
=m+7I
-----END PGP SIGNATURE-----
Merge tag 'for-3.8-rc1' of git://gitorious.org/linux-pwm/linux-pwm
Pull pwm changes from Thierry Reding:
"A new driver has been added for the SPEAr platform and the
TWL4030/6030 driver has been replaced by two drivers that control the
regular PWMs and the PWM driven LEDs provided by the chips.
The vt8500, tiecap, tiehrpwm, i.MX, LPC32xx and Samsung drivers have
all been improved and the device tree bindings now support the PWM
signal polarity."
Fix up trivial conflicts due to __devinit/exit removal.
* tag 'for-3.8-rc1' of git://gitorious.org/linux-pwm/linux-pwm: (21 commits)
pwm: samsung: add missing s3c->pwm_id assignment
pwm: lpc32xx: Set the chip base for dynamic allocation
pwm: lpc32xx: Properly disable the clock on device removal
pwm: lpc32xx: Fix the PWM polarity
pwm: i.MX: eliminate build warning
pwm: Export of_pwm_xlate_with_flags()
pwm: Remove pwm-twl6030 driver
pwm: New driver to support PWM driven LEDs on TWL4030/6030 series of PMICs
pwm: New driver to support PWMs on TWL4030/6030 series of PMICs
pwm: pwm-tiehrpwm: pinctrl support
pwm: tiehrpwm: Add device-tree binding
pwm: pwm-tiehrpwm: Adding TBCLK gating support.
pwm: pwm-tiecap: pinctrl support
pwm: tiecap: Add device-tree binding
pwm: Add TI PWM subsystem driver
pwm: Device tree support for PWM polarity
pwm: vt8500: Ensure PWM clock is enabled during pwm_config
pwm: vt8500: Fix build error
pwm: spear: Staticize spear_pwm_config()
pwm: Add SPEAr PWM chip driver support
...
Doing so allows the base to be allocated dynamically at runtime and
makes it easier for the chip to coexist with other PWM chips.
Signed-off-by: Alban Bedel <alban.bedel@avionic-design.de>
Acked-by: Alexandre Pereira da Silva <aletes.xgr@gmail.com>
Acked-by: Roland Stigge <stigge@antcom.de>
Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
A single clock is used for all PWMs meaning the clock's reference count
might be between 0 and N when .remove() is called. Instead of a single
clk_disable() call pwm_disable() on each PWM, to ensure that
clk_disable() is called for each PWM that is still enabled.
Signed-off-by: Alban Bedel <alban.bedel@avionic-design.de>
Acked-by: Alexandre Pereira da Silva <aletes.xgr@gmail.com>
Acked-by: Roland Stigge <stigge@antcom.de>
Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
The duty cycles value goes from 1 (99% HIGH) to 256 (0% HIGH) but it
is stored modulo 256 in the register as it is only 8 bits wide.
Signed-off-by: Alban Bedel <alban.bedel@avionic-design.de>
Acked-by: Alexandre Pereira da Silva <aletes.xgr@gmail.com>
Acked-by: Roland Stigge <stigge@antcom.de>
Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
CONFIG_HOTPLUG is going away as an option so __devexit is no
longer needed.
Signed-off-by: Bill Pemberton <wfp5p@virginia.edu>
Acked-by: Thierry Reding <thierry.reding@avionic-design.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
CONFIG_HOTPLUG is going away as an option so __devexit_p is no longer
needed.
Signed-off-by: Bill Pemberton <wfp5p@virginia.edu>
Acked-by: Thierry Reding <thierry.reding@avionic-design.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>