* [PATCH] Add pwm core support @ 2012-01-31 9:36 Sascha Hauer 2012-02-01 8:20 ` Robert Jarzmik 2012-02-01 22:42 ` [PATCH] drivers/pwm: add PXA pulse width modulator controller Robert Jarzmik 0 siblings, 2 replies; 19+ messages in thread From: Sascha Hauer @ 2012-01-31 9:36 UTC (permalink / raw) To: barebox This patch adds framework support for PWM (pulse width modulation) devices. A new pwm can be registered from a hardware driver using pwmchip_add(). It can then be requested from a client driver using pwm_request(). A string is used as a unique identifier for the pwms. It should usually be initialized by the hardware drivers using dev_name(dev). The client API is the same as currently in the Linux Kernel. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- This patch is currently compile tested only due to the lack of client drivers. drivers/Kconfig | 2 + drivers/Makefile | 1 + drivers/pwm/Kconfig | 12 ++++ drivers/pwm/Makefile | 1 + drivers/pwm/core.c | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/pwm.h | 63 +++++++++++++++++++ 6 files changed, 242 insertions(+), 0 deletions(-) create mode 100644 drivers/pwm/Kconfig create mode 100644 drivers/pwm/Makefile create mode 100644 drivers/pwm/core.c create mode 100644 include/pwm.h diff --git a/drivers/Kconfig b/drivers/Kconfig index c4e1517..52eedd9 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -15,4 +15,6 @@ source "drivers/mfd/Kconfig" source "drivers/led/Kconfig" source "drivers/eeprom/Kconfig" +source "drivers/pwm/Kconfig" + endmenu diff --git a/drivers/Makefile b/drivers/Makefile index 592c39e..380c2f1 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -13,3 +13,4 @@ obj-y += clk/ obj-y += mfd/ obj-$(CONFIG_LED) += led/ obj-y += eeprom/ +obj-$(CONFIG_PWM) += pwm/ diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig new file mode 100644 index 0000000..93c1052 --- /dev/null +++ b/drivers/pwm/Kconfig @@ -0,0 +1,12 @@ +menuconfig PWM + bool "PWM Support" + help + This enables PWM support through the generic PWM framework. + You only need to enable this, if you also want to enable + one or more of the PWM drivers below. + + If unsure, say N. + +if PWM + +endif diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile new file mode 100644 index 0000000..3469c3d --- /dev/null +++ b/drivers/pwm/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_PWM) += core.o diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c new file mode 100644 index 0000000..af30edf --- /dev/null +++ b/drivers/pwm/core.c @@ -0,0 +1,163 @@ +/* + * Generic pwmlib implementation + * + * Copyright (C) 2011 Sascha Hauer <s.hauer@pengutronix.de> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#include <common.h> +#include <errno.h> +#include <malloc.h> +#include <pwm.h> +#include <linux/list.h> + +struct pwm_device { + struct pwm_chip *chip; + unsigned long flags; +#define FLAG_REQUESTED 0 +#define FLAG_ENABLED 1 + struct list_head node; +}; + +static LIST_HEAD(pwm_list); + +static struct pwm_device *_find_pwm(const char *devname) +{ + struct pwm_device *pwm; + + list_for_each_entry(pwm, &pwm_list, node) { + if (!strcmp(pwm->chip->devname, devname)) + return pwm; + } + + return NULL; +} + +/** + * pwmchip_add() - register a new pwm + * @chip: the pwm + * + * register a new pwm. pwm->devname must be initialized, usually + * from dev_name(dev) from the hardware driver. + */ +int pwmchip_add(struct pwm_chip *chip) +{ + struct pwm_device *pwm; + int ret = 0; + + if (_find_pwm(chip->devname)) + return -EBUSY; + + pwm = xzalloc(sizeof(*pwm)); + pwm->chip = chip; + + list_add_tail(&pwm->node, &pwm_list); + + return ret; +} +EXPORT_SYMBOL_GPL(pwmchip_add); + +/** + * pwmchip_remove() - remove a pwm + * @chip: the pwm + * + * remove a pwm. This function may return busy if the pwm is still requested. + */ +int pwmchip_remove(struct pwm_chip *chip) +{ + struct pwm_device *pwm; + + pwm = _find_pwm(chip->devname); + if (!pwm) + return -ENOENT; + + if (test_bit(FLAG_REQUESTED, &pwm->flags)) + return -EBUSY; + + list_del(&pwm->node); + + kfree(pwm); + + return 0; +} +EXPORT_SYMBOL_GPL(pwmchip_remove); + +/* + * pwm_request - request a PWM device + */ +struct pwm_device *pwm_request(const char *devname) +{ + struct pwm_device *pwm; + int ret; + + pwm = _find_pwm(devname); + if (!pwm) + return NULL; + + if (test_bit(FLAG_REQUESTED, &pwm->flags)) + return NULL; + + if (pwm->chip->ops->request) { + ret = pwm->chip->ops->request(pwm->chip); + if (ret) + return NULL; + } + + set_bit(FLAG_REQUESTED, &pwm->flags); + + return pwm; +} +EXPORT_SYMBOL_GPL(pwm_request); + +/* + * pwm_free - free a PWM device + */ +void pwm_free(struct pwm_device *pwm) +{ + if (!test_and_clear_bit(FLAG_REQUESTED, &pwm->flags)) + return; +} +EXPORT_SYMBOL_GPL(pwm_free); + +/* + * pwm_config - change a PWM device configuration + */ +int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) +{ + return pwm->chip->ops->config(pwm->chip, duty_ns, period_ns); +} +EXPORT_SYMBOL_GPL(pwm_config); + +/* + * pwm_enable - start a PWM output toggling + */ +int pwm_enable(struct pwm_device *pwm) +{ + if (!test_and_set_bit(FLAG_ENABLED, &pwm->flags)) + return pwm->chip->ops->enable(pwm->chip); + + return 0; +} +EXPORT_SYMBOL_GPL(pwm_enable); + +/* + * pwm_disable - stop a PWM output toggling + */ +void pwm_disable(struct pwm_device *pwm) +{ + if (test_and_clear_bit(FLAG_ENABLED, &pwm->flags)) + pwm->chip->ops->disable(pwm->chip); +} +EXPORT_SYMBOL_GPL(pwm_disable); diff --git a/include/pwm.h b/include/pwm.h new file mode 100644 index 0000000..80f88b1 --- /dev/null +++ b/include/pwm.h @@ -0,0 +1,63 @@ +#ifndef __PWM_H +#define __PWM_H + +struct pwm_device; + +/* + * pwm_request - request a PWM device + */ +struct pwm_device *pwm_request(const char *pwmname); + +/* + * pwm_free - free a PWM device + */ +void pwm_free(struct pwm_device *pwm); + +/* + * pwm_config - change a PWM device configuration + */ +int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns); + +/* + * pwm_enable - start a PWM output toggling + */ +int pwm_enable(struct pwm_device *pwm); + +/* + * pwm_disable - stop a PWM output toggling + */ +void pwm_disable(struct pwm_device *pwm); + +struct pwm_chip; + +/** + * struct pwm_ops - PWM operations + * @request: optional hook for requesting a PWM + * @free: optional hook for freeing a PWM + * @config: configure duty cycles and period length for this PWM + * @enable: enable PWM output toggling + * @disable: disable PWM output toggling + */ +struct pwm_ops { + int (*request)(struct pwm_chip *chip); + void (*free)(struct pwm_chip *chip); + int (*config)(struct pwm_chip *chip, int duty_ns, + int period_ns); + int (*enable)(struct pwm_chip *chip); + void (*disable)(struct pwm_chip *chip); +}; + +/** + * struct pwm_chip - abstract a PWM + * @devname: unique identifier for this pwm + * @ops: The callbacks for this PWM + */ +struct pwm_chip { + const char *devname; + struct pwm_ops *ops; +}; + +int pwmchip_add(struct pwm_chip *chip); +int pwmchip_remove(struct pwm_chip *chip); + +#endif /* __PWM_H */ -- 1.7.8.3 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] Add pwm core support 2012-01-31 9:36 [PATCH] Add pwm core support Sascha Hauer @ 2012-02-01 8:20 ` Robert Jarzmik 2012-02-01 22:42 ` [PATCH] drivers/pwm: add PXA pulse width modulator controller Robert Jarzmik 1 sibling, 0 replies; 19+ messages in thread From: Robert Jarzmik @ 2012-02-01 8:20 UTC (permalink / raw) To: Sascha Hauer; +Cc: barebox Sascha Hauer <s.hauer@pengutronix.de> writes: > This patch adds framework support for PWM (pulse width modulation) > devices. > A new pwm can be registered from a hardware driver using > pwmchip_add(). It can then be requested from a client driver using > pwm_request(). A string is used as a unique identifier for the > pwms. It should usually be initialized by the hardware drivers > using dev_name(dev). The client API is the same as currently > in the Linux Kernel. > > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> > --- > > This patch is currently compile tested only due to the lack of > client drivers. You can add my : Tested-by: Robert Jarzmik <robert.jarzmik@free.fr> And I'll post the pxa pwm driver which I developped on top on that framework today, with which I'm pretty sure your core works, because my screen backlight ignites :) Cheers. -- Robert _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH] drivers/pwm: add PXA pulse width modulator controller 2012-01-31 9:36 [PATCH] Add pwm core support Sascha Hauer 2012-02-01 8:20 ` Robert Jarzmik @ 2012-02-01 22:42 ` Robert Jarzmik 2012-02-03 9:52 ` Sascha Hauer 1 sibling, 1 reply; 19+ messages in thread From: Robert Jarzmik @ 2012-02-01 22:42 UTC (permalink / raw) To: barebox, s.hauer Add PXA embedded pulse width modulator support. The PWM can generate signals from 49.6kHz to 1.625MHz. The driver is for pxa2xx family. The pxa3xx was not handled yet. Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr> --- arch/arm/mach-pxa/Makefile | 1 + arch/arm/mach-pxa/include/mach/clock.h | 1 + arch/arm/mach-pxa/include/mach/regs-pwm.h | 20 ++++ arch/arm/mach-pxa/speed-pxa27x.c | 5 + drivers/pwm/Kconfig | 6 + drivers/pwm/Makefile | 1 + drivers/pwm/pxa_pwm.c | 163 +++++++++++++++++++++++++++++ 7 files changed, 197 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-pxa/include/mach/regs-pwm.h create mode 100644 drivers/pwm/pxa_pwm.c diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index c01a9e0..6a02a54 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -1,6 +1,7 @@ obj-y += clocksource.o obj-y += common.o obj-y += gpio.o +obj-y += devices.o obj-$(CONFIG_ARCH_PXA2XX) += mfp-pxa2xx.o obj-$(CONFIG_ARCH_PXA27X) += speed-pxa27x.o diff --git a/arch/arm/mach-pxa/include/mach/clock.h b/arch/arm/mach-pxa/include/mach/clock.h index c53432f..f86152f 100644 --- a/arch/arm/mach-pxa/include/mach/clock.h +++ b/arch/arm/mach-pxa/include/mach/clock.h @@ -14,5 +14,6 @@ unsigned long pxa_get_uartclk(void); unsigned long pxa_get_mmcclk(void); unsigned long pxa_get_lcdclk(void); +unsigned long pxa_get_pwmclk(void); #endif /* !__MACH_CLOCK_H */ diff --git a/arch/arm/mach-pxa/include/mach/regs-pwm.h b/arch/arm/mach-pxa/include/mach/regs-pwm.h new file mode 100644 index 0000000..9fdcbb6 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/regs-pwm.h @@ -0,0 +1,20 @@ +/* + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ASM_MACH_REGS_PWM_H +#define __ASM_MACH_REGS_PWM_H + +#include <mach/hardware.h> + +/* + * Pulse modulator registers + */ +#define PWM0 0x40B00000 +#define PWM1 0x40C00000 +#define PWM0slave 0x40B00010 +#define PWM1slave 0x40C00010 + +#endif diff --git a/arch/arm/mach-pxa/speed-pxa27x.c b/arch/arm/mach-pxa/speed-pxa27x.c index 534eb1d..1de034c 100644 --- a/arch/arm/mach-pxa/speed-pxa27x.c +++ b/arch/arm/mach-pxa/speed-pxa27x.c @@ -47,3 +47,8 @@ unsigned long pxa_get_lcdclk(void) { return pxa_get_lcdclk_10khz() * 10000; } + +unsigned long pxa_get_pwmclk(void) +{ + return BASE_CLK; +} diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index 93c1052..50c956a 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -8,5 +8,11 @@ menuconfig PWM If unsure, say N. if PWM +config PWM_PXA + bool "PXA PWM Support" + default y if ARCH_PXA2XX + help + This enables PWM support for Intel/Marvell PXA chips, such + as the PXA25x, PXA27x. endif diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile index 3469c3d..c886bd5 100644 --- a/drivers/pwm/Makefile +++ b/drivers/pwm/Makefile @@ -1 +1,2 @@ obj-$(CONFIG_PWM) += core.o +obj-$(CONFIG_PWM_PXA) += pxa_pwm.o \ No newline at end of file diff --git a/drivers/pwm/pxa_pwm.c b/drivers/pwm/pxa_pwm.c new file mode 100644 index 0000000..bb114aa --- /dev/null +++ b/drivers/pwm/pxa_pwm.c @@ -0,0 +1,163 @@ +/* + * simple driver for PWM (Pulse Width Modulator) controller + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 2008-02-13 initial version + * eric miao <eric.miao@marvell.com> + * 2012 Robert Jarzmik <robert.jarzmik@free.fr> + */ + +#include <common.h> +#include <init.h> +#include <errno.h> +#include <io.h> +#include <pwm.h> + +#include <mach/hardware.h> +#include <mach/clock.h> +#include <mach/pxa-regs.h> +#include <mach/regs-pwm.h> +#include <asm-generic/div64.h> +#include <linux/compiler.h> + +/* PWM registers and bits definitions */ +#define PWMCR (0x00) +#define PWMDCR (0x04) +#define PWMPCR (0x08) + +#define PWMCR_SD (1 << 6) +#define PWMDCR_FD (1 << 10) + +#ifdef CONFIG_PWM + +static int pwm_get_pwm_idx(struct pwm_chip *chip) +{ + if (!strncmp(chip->devname, "pxa_pwm0", 8)) + return 0; + else if (!strncmp(chip->devname, "pxa_pwm1", 8)) + return 1; + else + return -EINVAL; +} + +static void __iomem *pwm_bases[] = { + (void __iomem *)PWM0, + (void __iomem *)PWM1, + (void __iomem *)PWM0slave, + (void __iomem *)PWM1slave, +}; + +/* + * period_ns = 10^9 * (PRESCALE + 1) * (PV + 1) / PWM_CLK_RATE + * duty_ns = 10^9 * (PRESCALE + 1) * DC / PWM_CLK_RATE + * PWM_CLK_RATE = 13 MHz + */ +static int pxa_pwm_config(struct pwm_chip *chip, int duty_ns, int period_ns) +{ + int pwm_idx; + unsigned long long c; + unsigned long period_cycles, prescale, pv, dc; + void __iomem *iobase; + + pwm_idx = pwm_get_pwm_idx(chip); + if (pwm_idx < 0 || period_ns == 0 || duty_ns > period_ns) + return -EINVAL; + iobase = pwm_bases[pwm_idx]; + + c = pxa_get_pwmclk(); + c = c * period_ns; + do_div(c, 1000000000); + period_cycles = c; + + if (period_cycles < 1) + period_cycles = 1; + prescale = (period_cycles - 1) / 1024; + pv = period_cycles / (prescale + 1) - 1; + + if (prescale > 63) + return -EINVAL; + + if (duty_ns == period_ns) + dc = PWMDCR_FD; + else + dc = (pv + 1) * duty_ns / period_ns; + + /* NOTE: the clock to PWM has to be enabled first + * before writing to the registers + */ + __raw_writel(prescale, iobase + PWMCR); + __raw_writel(dc, iobase + PWMDCR); + __raw_writel(pv, iobase + PWMPCR); + + return 0; +} + +static int pxa_pwm_enable(struct pwm_chip *chip) +{ + switch (pwm_get_pwm_idx(chip)) { + case 0: + CKEN |= CKEN_PWM0; + break; + case 1: + CKEN |= CKEN_PWM1; + break; + default: + return -EINVAL; + } + return 0; +} + +static void pxa_pwm_disable(struct pwm_chip *chip) +{ + switch (pwm_get_pwm_idx(chip)) { + case 0: + CKEN &= ~CKEN_PWM0; + break; + case 1: + CKEN &= ~CKEN_PWM1; + break; + default: + break; + } +} + +static struct pwm_ops pxa_pwm_ops = { + .config = pxa_pwm_config, + .enable = pxa_pwm_enable, + .disable = pxa_pwm_disable, +}; + +#define DECLARE_PXA_PWM(name) \ + static struct pwm_chip name = { \ + .devname = #name, \ + .ops = &pxa_pwm_ops, \ +} + +DECLARE_PXA_PWM(pxa_pwm0); +DECLARE_PXA_PWM(pxa_pwm1); +DECLARE_PXA_PWM(pxa_pwm0slave); +DECLARE_PXA_PWM(pxa_pwm1slave); + +static int pxa_pwm_init(void) +{ + CKEN &= ~CKEN_PWM0 & ~CKEN_PWM1; + pwmchip_add(&pxa_pwm0); + pwmchip_add(&pxa_pwm1); + if (cpu_is_pxa27x()) { + pwmchip_add(&pxa_pwm0slave); + pwmchip_add(&pxa_pwm1slave); + } + return 0; +} + +#else +static int pxa_pwm_init(void) +{ + return 0; +} +#endif + +coredevice_initcall(pxa_pwm_init); -- 1.7.5.4 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] drivers/pwm: add PXA pulse width modulator controller 2012-02-01 22:42 ` [PATCH] drivers/pwm: add PXA pulse width modulator controller Robert Jarzmik @ 2012-02-03 9:52 ` Sascha Hauer 2012-02-03 15:39 ` Robert Jarzmik 0 siblings, 1 reply; 19+ messages in thread From: Sascha Hauer @ 2012-02-03 9:52 UTC (permalink / raw) To: Robert Jarzmik; +Cc: barebox Hi Robert, On Wed, Feb 01, 2012 at 11:42:28PM +0100, Robert Jarzmik wrote: > Add PXA embedded pulse width modulator support. The PWM can > generate signals from 49.6kHz to 1.625MHz. > The driver is for pxa2xx family. The pxa3xx was not handled yet. Why not implement it as a regular driver? If we ever want to implement a commandline control of the pwms via pwm0.dutyns=xx we'll need a struct device. Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] drivers/pwm: add PXA pulse width modulator controller 2012-02-03 9:52 ` Sascha Hauer @ 2012-02-03 15:39 ` Robert Jarzmik 2012-02-08 15:26 ` Robert Jarzmik 0 siblings, 1 reply; 19+ messages in thread From: Robert Jarzmik @ 2012-02-03 15:39 UTC (permalink / raw) To: Sascha Hauer; +Cc: barebox Sascha Hauer <s.hauer@pengutronix.de> writes: > Hi Robert, > > Why not implement it as a regular driver? If we ever want to implement > a commandline control of the pwms via pwm0.dutyns=xx we'll need > a struct device. This is because in my own case, I need pwm to be registered before other devices are probed. The trouble (in my case) is that for drivers/video/pxa.c, I have the following call path : - pxafb_probe() -> pxafb_enable_controller() -> pxafb_backlight_power() -> mioa701_lcd_backlight() => struct pwm_device *pwm0 = pwm_request("pxa_pwm0"); pwm_enable(pwm0); pwm_config(pwm0, 2000 * 1024, 4000 * 1024); I'm a bit afraid that the pxafb driver will be probed first, before pwm_pxa, and therefore the backlight setting won't work. I haven't found a clean way to specify this dependency. Cheers. -- Robert _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] drivers/pwm: add PXA pulse width modulator controller 2012-02-03 15:39 ` Robert Jarzmik @ 2012-02-08 15:26 ` Robert Jarzmik 2012-02-09 8:10 ` Sascha Hauer 0 siblings, 1 reply; 19+ messages in thread From: Robert Jarzmik @ 2012-02-08 15:26 UTC (permalink / raw) To: Sascha Hauer; +Cc: barebox Robert Jarzmik <robert.jarzmik@free.fr> writes: > Sascha Hauer <s.hauer@pengutronix.de> writes: > >> Hi Robert, >> >> Why not implement it as a regular driver? If we ever want to implement >> a commandline control of the pwms via pwm0.dutyns=xx we'll need >> a struct device. > > This is because in my own case, I need pwm to be registered before other devices > are probed. The trouble (in my case) is that for drivers/video/pxa.c, I have the > following call path : > - pxafb_probe() > -> pxafb_enable_controller() > -> pxafb_backlight_power() > -> mioa701_lcd_backlight() > => struct pwm_device *pwm0 = pwm_request("pxa_pwm0"); > pwm_enable(pwm0); > pwm_config(pwm0, 2000 * 1024, 4000 * 1024); > > I'm a bit afraid that the pxafb driver will be probed first, before pwm_pxa, and > therefore the backlight setting won't work. I haven't found a clean way to > specify this dependency. Sascha, ping ? Do you have a way to specify the dependency, and do you want me to adapt the driver ? Cheers. -- Robert _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] drivers/pwm: add PXA pulse width modulator controller 2012-02-08 15:26 ` Robert Jarzmik @ 2012-02-09 8:10 ` Sascha Hauer 2012-02-09 11:50 ` Robert Jarzmik 0 siblings, 1 reply; 19+ messages in thread From: Sascha Hauer @ 2012-02-09 8:10 UTC (permalink / raw) To: Robert Jarzmik; +Cc: barebox On Wed, Feb 08, 2012 at 04:26:21PM +0100, Robert Jarzmik wrote: > Robert Jarzmik <robert.jarzmik@free.fr> writes: > > > Sascha Hauer <s.hauer@pengutronix.de> writes: > > > >> Hi Robert, > >> > >> Why not implement it as a regular driver? If we ever want to implement > >> a commandline control of the pwms via pwm0.dutyns=xx we'll need > >> a struct device. > > > > This is because in my own case, I need pwm to be registered before other devices > > are probed. The trouble (in my case) is that for drivers/video/pxa.c, I have the > > following call path : > > - pxafb_probe() > > -> pxafb_enable_controller() > > -> pxafb_backlight_power() > > -> mioa701_lcd_backlight() > > => struct pwm_device *pwm0 = pwm_request("pxa_pwm0"); > > pwm_enable(pwm0); > > pwm_config(pwm0, 2000 * 1024, 4000 * 1024); > > > > I'm a bit afraid that the pxafb driver will be probed first, before pwm_pxa, and > > therefore the backlight setting won't work. I haven't found a clean way to > > specify this dependency. > > Sascha, ping ? > > Do you have a way to specify the dependency, and do you want me to adapt the > driver ? Sorry, I wanted to think about this issue and appearently forgot about it. So the moment has come we have the same problems as in the kernel: we can't express the dependencies between devices. For your case I think we can get around the problem once more. Experience shows that the framebuffer shouldn't be enabled on initialization time. If it does you end up with a framebuffer showing a blank screen in the best case. Instead the framebuffer should be enabled explicitely once there is an image on the screen which looks much nicer to the user. That said the following should be removed from the pxafb driver: if (pdata->enable_on_load) info->fbops->fb_enable(info); Are you ok with that? Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] drivers/pwm: add PXA pulse width modulator controller 2012-02-09 8:10 ` Sascha Hauer @ 2012-02-09 11:50 ` Robert Jarzmik 2012-02-09 13:44 ` Sascha Hauer 2012-02-14 12:58 ` [PATCH V2 1/2] " Robert Jarzmik 0 siblings, 2 replies; 19+ messages in thread From: Robert Jarzmik @ 2012-02-09 11:50 UTC (permalink / raw) To: Sascha Hauer; +Cc: barebox Sascha Hauer <s.hauer@pengutronix.de> writes: > Experience shows that the framebuffer shouldn't be enabled on > initialization time. If it does you end up with a framebuffer showing > a blank screen in the best case. Instead the framebuffer should be > enabled explicitely once there is an image on the screen which looks > much nicer to the user. That said the following should be removed from > the pxafb driver: > > if (pdata->enable_on_load) > info->fbops->fb_enable(info); > > Are you ok with that? For the pxafb, yes agreed. I still see a small issue with the PWM API. When I register the pxa-pwm driver, I have : pxa_pwm_probe(struct device_d *dev) -> base = dev_request_mem_region(dev, 0); -> pxa_pwm = xzalloc(...) -> pxa_pwm->name = drv_name(...) -> pxa_pwm->ops = &pxa_pwm_ops, -> pwmchip_add(pxa_pwm) As you can see, the "base" is lost, and I have no way to store it in the pwm_chip structure. Shouldn't the pwm_chip structure have a priv pointer ? Cheers. -- Robert _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] drivers/pwm: add PXA pulse width modulator controller 2012-02-09 11:50 ` Robert Jarzmik @ 2012-02-09 13:44 ` Sascha Hauer 2012-02-09 14:30 ` Robert Jarzmik 2012-02-14 12:58 ` [PATCH V2 1/2] " Robert Jarzmik 1 sibling, 1 reply; 19+ messages in thread From: Sascha Hauer @ 2012-02-09 13:44 UTC (permalink / raw) To: Robert Jarzmik; +Cc: barebox On Thu, Feb 09, 2012 at 12:50:17PM +0100, Robert Jarzmik wrote: > Sascha Hauer <s.hauer@pengutronix.de> writes: > > Experience shows that the framebuffer shouldn't be enabled on > > initialization time. If it does you end up with a framebuffer showing > > a blank screen in the best case. Instead the framebuffer should be > > enabled explicitely once there is an image on the screen which looks > > much nicer to the user. That said the following should be removed from > > the pxafb driver: > > > > if (pdata->enable_on_load) > > info->fbops->fb_enable(info); > > > > Are you ok with that? > For the pxafb, yes agreed. > > I still see a small issue with the PWM API. > When I register the pxa-pwm driver, I have : > pxa_pwm_probe(struct device_d *dev) > -> base = dev_request_mem_region(dev, 0); > -> pxa_pwm = xzalloc(...) > -> pxa_pwm->name = drv_name(...) > -> pxa_pwm->ops = &pxa_pwm_ops, > -> pwmchip_add(pxa_pwm) > > As you can see, the "base" is lost, and I have no way to store it in the > pwm_chip structure. > > Shouldn't the pwm_chip structure have a priv pointer ? The intention was to put a struct pwm_chip into a struct pxa_pwm_chip and use container_of. Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH] drivers/pwm: add PXA pulse width modulator controller 2012-02-09 13:44 ` Sascha Hauer @ 2012-02-09 14:30 ` Robert Jarzmik 0 siblings, 0 replies; 19+ messages in thread From: Robert Jarzmik @ 2012-02-09 14:30 UTC (permalink / raw) To: Sascha Hauer; +Cc: barebox Sascha Hauer <s.hauer@pengutronix.de> writes: > The intention was to put a struct pwm_chip into a struct pxa_pwm_chip > and use container_of. Ah ok, I understand now. I will submit a V2 of my patch soon. Cheers. -- Robert _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH V2 1/2] drivers/pwm: add PXA pulse width modulator controller 2012-02-09 11:50 ` Robert Jarzmik 2012-02-09 13:44 ` Sascha Hauer @ 2012-02-14 12:58 ` Robert Jarzmik 2012-02-14 12:58 ` [PATCH V2 2/2] drivers/video: remove pxafb enable on load Robert Jarzmik 2012-02-15 8:32 ` [PATCH V2 1/2] drivers/pwm: add PXA pulse width modulator controller Sascha Hauer 1 sibling, 2 replies; 19+ messages in thread From: Robert Jarzmik @ 2012-02-14 12:58 UTC (permalink / raw) To: barebox Add PXA embedded pulse width modulator support. The PWM can generate signals from 49.6kHz to 1.625MHz. The driver is for pxa2xx family. The pxa3xx was not handled yet. Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr> --- arch/arm/mach-pxa/Makefile | 1 + arch/arm/mach-pxa/devices.c | 5 + arch/arm/mach-pxa/include/mach/clock.h | 1 + arch/arm/mach-pxa/include/mach/devices.h | 2 +- arch/arm/mach-pxa/include/mach/regs-pwm.h | 20 +++ arch/arm/mach-pxa/speed-pxa27x.c | 5 + drivers/pwm/Kconfig | 6 + drivers/pwm/Makefile | 1 + drivers/pwm/pxa_pwm.c | 219 +++++++++++++++++++++++++++++ 9 files changed, 259 insertions(+), 1 deletions(-) create mode 100644 arch/arm/mach-pxa/include/mach/regs-pwm.h create mode 100644 drivers/pwm/pxa_pwm.c diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index c01a9e0..6a02a54 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -1,6 +1,7 @@ obj-y += clocksource.o obj-y += common.o obj-y += gpio.o +obj-y += devices.o obj-$(CONFIG_ARCH_PXA2XX) += mfp-pxa2xx.o obj-$(CONFIG_ARCH_PXA27X) += speed-pxa27x.o diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index 1a396f1..b6ac0ba 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c @@ -47,3 +47,8 @@ struct device_d *pxa_add_mmc(void *base, int id, void *pdata) { return pxa_add_device("pxa-mmc", id, base, 0x1000, pdata); } + +struct device_d *pxa_add_pwm(void *base, int id) +{ + return pxa_add_device("pxa_pwm", id, base, 0x10, NULL); +} diff --git a/arch/arm/mach-pxa/include/mach/clock.h b/arch/arm/mach-pxa/include/mach/clock.h index c53432f..f86152f 100644 --- a/arch/arm/mach-pxa/include/mach/clock.h +++ b/arch/arm/mach-pxa/include/mach/clock.h @@ -14,5 +14,6 @@ unsigned long pxa_get_uartclk(void); unsigned long pxa_get_mmcclk(void); unsigned long pxa_get_lcdclk(void); +unsigned long pxa_get_pwmclk(void); #endif /* !__MACH_CLOCK_H */ diff --git a/arch/arm/mach-pxa/include/mach/devices.h b/arch/arm/mach-pxa/include/mach/devices.h index e205b7c..8390153 100644 --- a/arch/arm/mach-pxa/include/mach/devices.h +++ b/arch/arm/mach-pxa/include/mach/devices.h @@ -23,4 +23,4 @@ struct device_d *pxa_add_i2c(void *base, int id, struct device_d *pxa_add_uart(void *base, int id); struct device_d *pxa_add_fb(void *base, struct pxafb_platform_data *pdata); struct device_d *pxa_add_mmc(void *base, int id, void *pdata); - +struct device_d *pxa_add_pwm(void *base, int id); diff --git a/arch/arm/mach-pxa/include/mach/regs-pwm.h b/arch/arm/mach-pxa/include/mach/regs-pwm.h new file mode 100644 index 0000000..9fdcbb6 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/regs-pwm.h @@ -0,0 +1,20 @@ +/* + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ASM_MACH_REGS_PWM_H +#define __ASM_MACH_REGS_PWM_H + +#include <mach/hardware.h> + +/* + * Pulse modulator registers + */ +#define PWM0 0x40B00000 +#define PWM1 0x40C00000 +#define PWM0slave 0x40B00010 +#define PWM1slave 0x40C00010 + +#endif diff --git a/arch/arm/mach-pxa/speed-pxa27x.c b/arch/arm/mach-pxa/speed-pxa27x.c index 534eb1d..1de034c 100644 --- a/arch/arm/mach-pxa/speed-pxa27x.c +++ b/arch/arm/mach-pxa/speed-pxa27x.c @@ -47,3 +47,8 @@ unsigned long pxa_get_lcdclk(void) { return pxa_get_lcdclk_10khz() * 10000; } + +unsigned long pxa_get_pwmclk(void) +{ + return BASE_CLK; +} diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index 93c1052..50c956a 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -8,5 +8,11 @@ menuconfig PWM If unsure, say N. if PWM +config PWM_PXA + bool "PXA PWM Support" + default y if ARCH_PXA2XX + help + This enables PWM support for Intel/Marvell PXA chips, such + as the PXA25x, PXA27x. endif diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile index 3469c3d..c886bd5 100644 --- a/drivers/pwm/Makefile +++ b/drivers/pwm/Makefile @@ -1 +1,2 @@ obj-$(CONFIG_PWM) += core.o +obj-$(CONFIG_PWM_PXA) += pxa_pwm.o \ No newline at end of file diff --git a/drivers/pwm/pxa_pwm.c b/drivers/pwm/pxa_pwm.c new file mode 100644 index 0000000..f52d675 --- /dev/null +++ b/drivers/pwm/pxa_pwm.c @@ -0,0 +1,219 @@ +/* + * simple driver for PWM (Pulse Width Modulator) controller + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 2008-02-13 initial version + * eric miao <eric.miao@marvell.com> + * 2012 Robert Jarzmik <robert.jarzmik@free.fr> + */ + +#include <common.h> +#include <init.h> +#include <errno.h> +#include <io.h> +#include <pwm.h> + +#include <mach/hardware.h> +#include <mach/clock.h> +#include <mach/pxa-regs.h> +#include <mach/regs-pwm.h> +#include <asm-generic/div64.h> +#include <linux/compiler.h> + +/* PWM registers and bits definitions */ +#define PWMCR (0x00) +#define PWMDCR (0x04) +#define PWMPCR (0x08) + +#define PWMCR_SD (1 << 6) +#define PWMDCR_FD (1 << 10) + +struct pxa_pwm_chip { + struct pwm_chip chip; + void __iomem *iobase; + int id; + int duty_ns; + int period_ns; +}; + +static struct pxa_pwm_chip *to_pxa_pwm_chip(struct pwm_chip *chip) +{ + return container_of(chip, struct pxa_pwm_chip, chip); +} + +/* + * period_ns = 10^9 * (PRESCALE + 1) * (PV + 1) / PWM_CLK_RATE + * duty_ns = 10^9 * (PRESCALE + 1) * DC / PWM_CLK_RATE + * PWM_CLK_RATE = 13 MHz + */ +static int pxa_pwm_config(struct pwm_chip *chip, int duty_ns, int period_ns) +{ + unsigned long long c; + unsigned long period_cycles, prescale, pv, dc; + struct pxa_pwm_chip *pxa_pwm = to_pxa_pwm_chip(chip); + + c = pxa_get_pwmclk(); + c = c * period_ns; + do_div(c, 1000000000); + period_cycles = c; + + if (period_cycles < 1) + period_cycles = 1; + prescale = (period_cycles - 1) / 1024; + pv = period_cycles / (prescale + 1) - 1; + + if (prescale > 63) + return -EINVAL; + + if (duty_ns == period_ns) + dc = PWMDCR_FD; + else + dc = (pv + 1) * duty_ns / period_ns; + + pxa_pwm->duty_ns = duty_ns; + pxa_pwm->period_ns = period_ns; + + /* NOTE: the clock to PWM has to be enabled first + * before writing to the registers + */ + __raw_writel(prescale, pxa_pwm->iobase + PWMCR); + __raw_writel(dc, pxa_pwm->iobase + PWMDCR); + __raw_writel(pv, pxa_pwm->iobase + PWMPCR); + + return 0; +} + +static int pxa_pwm_enable(struct pwm_chip *chip) +{ + struct pxa_pwm_chip *pxa_pwm = to_pxa_pwm_chip(chip); + + switch (pxa_pwm->id) { + case 0: + case 2: + CKEN |= CKEN_PWM0; + break; + case 1: + case 3: + CKEN |= CKEN_PWM1; + break; + default: + return -EINVAL; + } + return 0; +} + +static void pxa_pwm_disable(struct pwm_chip *chip) +{ + struct pxa_pwm_chip *pxa_pwm = to_pxa_pwm_chip(chip); + + switch (pxa_pwm->id) { + case 0: + case 2: + CKEN &= ~CKEN_PWM0; + break; + case 1: + case 3: + CKEN &= ~CKEN_PWM1; + break; + default: + break; + } +} + +static struct pwm_ops pxa_pwm_ops = { + .config = pxa_pwm_config, + .enable = pxa_pwm_enable, + .disable = pxa_pwm_disable, +}; + +static int set_period_ns(struct device_d *dev, struct param_d *p, const char *val) +{ + struct pxa_pwm_chip *pxa_pwm = dev->priv; + int period_ns; + + if (!val) + return dev_param_set_generic(dev, p, NULL); + + period_ns = simple_strtoul(val, NULL, 0); + pxa_pwm_config(&pxa_pwm->chip, pxa_pwm->duty_ns, period_ns); + return dev_param_set_generic(dev, p, val); +} + +static int set_duty_ns(struct device_d *dev, struct param_d *p, const char *val) +{ + struct pxa_pwm_chip *pxa_pwm = dev->priv; + int duty_ns; + + if (!val) + return dev_param_set_generic(dev, p, NULL); + + duty_ns = simple_strtoul(val, NULL, 0); + pxa_pwm_config(&pxa_pwm->chip, duty_ns, pxa_pwm->period_ns); + return dev_param_set_generic(dev, p, val); +} + +static int set_enable(struct device_d *dev, struct param_d *p, const char *val) +{ + struct pxa_pwm_chip *pxa_pwm = dev->priv; + int enable; + + if (!val) + return dev_param_set_generic(dev, p, NULL); + + enable = !!simple_strtoul(val, NULL, 0); + if (enable) + pxa_pwm_enable(&pxa_pwm->chip); + else + pxa_pwm_disable(&pxa_pwm->chip); + return dev_param_set_generic(dev, p, enable ? "1" : "0"); +} + +static int __init pxa_pwm_register_vars(struct device_d *dev, + struct pxa_pwm_chip *pxa_pwm) +{ + int ret; + + ret = dev_add_param(dev, "duty_ns", set_duty_ns, NULL, 0); + if (!ret) + ret = dev_add_param(dev, "period_ns", set_period_ns, NULL, 0); + if (!ret) + ret = dev_add_param(dev, "enable", set_enable, NULL, 0); + if (!ret) + ret = dev_set_param(dev, "enable", 0); + return ret; +} + +static int pxa_pwm_probe(struct device_d *dev) +{ + struct pxa_pwm_chip *chip; + int ret; + + chip = xzalloc(sizeof(*chip)); + chip->chip.devname = asprintf("%s", dev_name(dev)); + chip->chip.ops = &pxa_pwm_ops; + chip->iobase = dev_request_mem_region(dev, 0); + chip->id = dev->id; + dev->priv = chip; + + ret = pwmchip_add(&chip->chip); + if (!ret) + ret = pxa_pwm_register_vars(dev, chip); + return ret; +} + +static struct driver_d pxa_pwm_driver = { + .name = "pxa_pwm", + .probe = pxa_pwm_probe, +}; + +static int __init pxa_pwm_init_driver(void) +{ + CKEN &= ~CKEN_PWM0 & ~CKEN_PWM1; + register_driver(&pxa_pwm_driver); + return 0; +} + +device_initcall(pxa_pwm_init_driver); -- 1.7.5.4 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH V2 2/2] drivers/video: remove pxafb enable on load 2012-02-14 12:58 ` [PATCH V2 1/2] " Robert Jarzmik @ 2012-02-14 12:58 ` Robert Jarzmik 2012-02-15 8:32 ` [PATCH V2 1/2] drivers/pwm: add PXA pulse width modulator controller Sascha Hauer 1 sibling, 0 replies; 19+ messages in thread From: Robert Jarzmik @ 2012-02-14 12:58 UTC (permalink / raw) To: barebox As pxafb can rely on a PWM to control backlight, and because driver dependencies are hard to deal with, remove automatic enable of PXAFB on probe. The user should in its environment do a : - fb0.enable=1 This way, the PWM has been probed and is ready to work, and the pxafb backlight control works. Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr> --- arch/arm/mach-pxa/include/mach/pxafb.h | 1 - drivers/video/pxa.c | 3 --- 2 files changed, 0 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-pxa/include/mach/pxafb.h b/arch/arm/mach-pxa/include/mach/pxafb.h index 1730fbf..23cbea9 100644 --- a/arch/arm/mach-pxa/include/mach/pxafb.h +++ b/arch/arm/mach-pxa/include/mach/pxafb.h @@ -64,7 +64,6 @@ struct pxafb_videomode { struct pxafb_platform_data { struct pxafb_videomode *mode; unsigned int lcd_conn; - int enable_on_load; /** force a memory area to be used, else NULL for dynamic allocation */ void *framebuffer; diff --git a/drivers/video/pxa.c b/drivers/video/pxa.c index ddd7087..900ae80 100644 --- a/drivers/video/pxa.c +++ b/drivers/video/pxa.c @@ -538,9 +538,6 @@ static int pxafb_probe(struct device_d *dev) return ret; } - if (pdata->enable_on_load) - info->fbops->fb_enable(info); - return 0; } -- 1.7.5.4 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH V2 1/2] drivers/pwm: add PXA pulse width modulator controller 2012-02-14 12:58 ` [PATCH V2 1/2] " Robert Jarzmik 2012-02-14 12:58 ` [PATCH V2 2/2] drivers/video: remove pxafb enable on load Robert Jarzmik @ 2012-02-15 8:32 ` Sascha Hauer 2012-02-15 11:22 ` Robert Jarzmik 2012-02-15 15:21 ` Robert Jarzmik 1 sibling, 2 replies; 19+ messages in thread From: Sascha Hauer @ 2012-02-15 8:32 UTC (permalink / raw) To: Robert Jarzmik; +Cc: barebox Hi Robert, On Tue, Feb 14, 2012 at 01:58:13PM +0100, Robert Jarzmik wrote: > Add PXA embedded pulse width modulator support. The PWM can > generate signals from 49.6kHz to 1.625MHz. > The driver is for pxa2xx family. The pxa3xx was not handled yet. > > Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr> > --- > arch/arm/mach-pxa/Makefile | 1 + > arch/arm/mach-pxa/devices.c | 5 + > arch/arm/mach-pxa/include/mach/clock.h | 1 + > arch/arm/mach-pxa/include/mach/devices.h | 2 +- > arch/arm/mach-pxa/include/mach/regs-pwm.h | 20 +++ > arch/arm/mach-pxa/speed-pxa27x.c | 5 + > drivers/pwm/Kconfig | 6 + > drivers/pwm/Makefile | 1 + > drivers/pwm/pxa_pwm.c | 219 +++++++++++++++++++++++++++++ > 9 files changed, 259 insertions(+), 1 deletions(-) > create mode 100644 arch/arm/mach-pxa/include/mach/regs-pwm.h > create mode 100644 drivers/pwm/pxa_pwm.c > > + > +static int __init pxa_pwm_register_vars(struct device_d *dev, > + struct pxa_pwm_chip *pxa_pwm) > +{ > + int ret; > + > + ret = dev_add_param(dev, "duty_ns", set_duty_ns, NULL, 0); > + if (!ret) > + ret = dev_add_param(dev, "period_ns", set_period_ns, NULL, 0); > + if (!ret) > + ret = dev_add_param(dev, "enable", set_enable, NULL, 0); > + if (!ret) > + ret = dev_set_param(dev, "enable", 0); > + return ret; > +} Nice to make the pwms accessible from the command line, but shouldn't this be in the core? From what I see all we have to do is to add duty_ns and period_ns to struct pwm_chip. Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH V2 1/2] drivers/pwm: add PXA pulse width modulator controller 2012-02-15 8:32 ` [PATCH V2 1/2] drivers/pwm: add PXA pulse width modulator controller Sascha Hauer @ 2012-02-15 11:22 ` Robert Jarzmik 2012-02-15 15:21 ` Robert Jarzmik 1 sibling, 0 replies; 19+ messages in thread From: Robert Jarzmik @ 2012-02-15 11:22 UTC (permalink / raw) To: Sascha Hauer; +Cc: barebox Sascha Hauer <s.hauer@pengutronix.de> writes: > Hi Robert, > > Nice to make the pwms accessible from the command line, but shouldn't > this be in the core? From what I see all we have to do is to add > duty_ns and period_ns to struct pwm_chip. > Ah yes, I didn't think about it :) I will send V3, with duty_ns, period_ns and enable transfered to pwm core. Cheers. -- Robert _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH V2 1/2] drivers/pwm: add PXA pulse width modulator controller 2012-02-15 8:32 ` [PATCH V2 1/2] drivers/pwm: add PXA pulse width modulator controller Sascha Hauer 2012-02-15 11:22 ` Robert Jarzmik @ 2012-02-15 15:21 ` Robert Jarzmik 2012-02-16 7:40 ` Sascha Hauer 1 sibling, 1 reply; 19+ messages in thread From: Robert Jarzmik @ 2012-02-15 15:21 UTC (permalink / raw) To: Sascha Hauer; +Cc: barebox Sascha Hauer <s.hauer@pengutronix.de> writes: > Hi Robert, > Nice to make the pwms accessible from the command line, but shouldn't > this be in the core? From what I see all we have to do is to add > duty_ns and period_ns to struct pwm_chip. I thought it over twice. If the set_duty_ns(), set_period_ns() and set_enable() are transfered to the core, I'll have to link the device and pwm_chip : - expand pwmadd_chip() : should be expanded with the "struct device_d *dev" parameter - provide a way to link *dev with *pwm_chip => either store device_d pointer into pwm_device structure, and go through the list of all PWMs at each set_X() calls => or use dev->priv (bad idea since the driver, ie. pxa_pwm wants to do that) This way, calling set_X(struct device_d *dev, ...) will find pwm_chip pointer from dev, and call the approriate pwm_config(), ... So it's a bit more that adding duty_ns and period_ns to struct pwm_chip. Is this what you want ? Cheers. -- Robert _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH V2 1/2] drivers/pwm: add PXA pulse width modulator controller 2012-02-15 15:21 ` Robert Jarzmik @ 2012-02-16 7:40 ` Sascha Hauer 2012-02-16 18:23 ` [PATCH V3 1/3] drivers/pwm: add duty_ns and period_ns to core pwm chip Robert Jarzmik 0 siblings, 1 reply; 19+ messages in thread From: Sascha Hauer @ 2012-02-16 7:40 UTC (permalink / raw) To: Robert Jarzmik; +Cc: barebox On Wed, Feb 15, 2012 at 04:21:13PM +0100, Robert Jarzmik wrote: > Sascha Hauer <s.hauer@pengutronix.de> writes: > > > Hi Robert, > > Nice to make the pwms accessible from the command line, but shouldn't > > this be in the core? From what I see all we have to do is to add > > duty_ns and period_ns to struct pwm_chip. > > I thought it over twice. > > If the set_duty_ns(), set_period_ns() and set_enable() are transfered to the > core, I'll have to link the device and pwm_chip : > - expand pwmadd_chip() : should be expanded with the "struct device_d *dev" > parameter > - provide a way to link *dev with *pwm_chip > => either store device_d pointer into pwm_device structure, and go through the > list of all PWMs at each set_X() calls > => or use dev->priv (bad idea since the driver, ie. pxa_pwm wants to do that) > > This way, calling set_X(struct device_d *dev, ...) will find pwm_chip pointer > from dev, and call the approriate pwm_config(), ... > > So it's a bit more that adding duty_ns and period_ns to struct pwm_chip. Is this > what you want ? Oh, yes, you are right. You have to add a struct device_d * to struct pwm_chip. Sascha -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH V3 1/3] drivers/pwm: add duty_ns and period_ns to core pwm chip 2012-02-16 7:40 ` Sascha Hauer @ 2012-02-16 18:23 ` Robert Jarzmik 2012-02-16 18:23 ` [PATCH V3 2/3] drivers/pwm: add PXA pulse width modulator controller Robert Jarzmik 2012-02-16 18:23 ` [PATCH V3 3/3] drivers/video: remove pxafb enable on load Robert Jarzmik 0 siblings, 2 replies; 19+ messages in thread From: Robert Jarzmik @ 2012-02-16 18:23 UTC (permalink / raw) To: barebox Add variables to control the duty_ns and period_ns of PWM chips. When these variables are set, a call to either pwm_enable() or pwm_config() is performed to enforce the setup values. Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr> --- drivers/pwm/core.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++- include/pwm.h | 7 ++++- 2 files changed, 81 insertions(+), 2 deletions(-) diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index af30edf..5895584 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -29,10 +29,23 @@ struct pwm_device { #define FLAG_REQUESTED 0 #define FLAG_ENABLED 1 struct list_head node; + struct device_d *dev; }; static LIST_HEAD(pwm_list); +static struct pwm_device *dev_to_pwm(struct device_d *dev) +{ + struct pwm_device *pwm; + + list_for_each_entry(pwm, &pwm_list, node) { + if (pwm->dev == dev) + return pwm; + } + + return NULL; +} + static struct pwm_device *_find_pwm(const char *devname) { struct pwm_device *pwm; @@ -45,6 +58,63 @@ static struct pwm_device *_find_pwm(const char *devname) return NULL; } +static int set_period_ns(struct device_d *dev, struct param_d *p, + const char *val) +{ + struct pwm_device *pwm = dev_to_pwm(dev); + int period_ns; + + if (!val) + return dev_param_set_generic(dev, p, NULL); + + period_ns = simple_strtoul(val, NULL, 0); + pwm_config(pwm, pwm->chip->duty_ns, period_ns); + return dev_param_set_generic(dev, p, val); +} + +static int set_duty_ns(struct device_d *dev, struct param_d *p, const char *val) +{ + struct pwm_device *pwm = dev_to_pwm(dev); + int duty_ns; + + if (!val) + return dev_param_set_generic(dev, p, NULL); + + duty_ns = simple_strtoul(val, NULL, 0); + pwm_config(pwm, duty_ns, pwm->chip->period_ns); + return dev_param_set_generic(dev, p, val); +} + +static int set_enable(struct device_d *dev, struct param_d *p, const char *val) +{ + struct pwm_device *pwm = dev_to_pwm(dev); + int enable; + + if (!val) + return dev_param_set_generic(dev, p, NULL); + + enable = !!simple_strtoul(val, NULL, 0); + if (enable) + pwm_enable(pwm); + else + pwm_disable(pwm); + return dev_param_set_generic(dev, p, enable ? "1" : "0"); +} + +static int pwm_register_vars(struct device_d *dev) +{ + int ret; + + ret = dev_add_param(dev, "duty_ns", set_duty_ns, NULL, 0); + if (!ret) + ret = dev_add_param(dev, "period_ns", set_period_ns, NULL, 0); + if (!ret) + ret = dev_add_param(dev, "enable", set_enable, NULL, 0); + if (!ret) + ret = dev_set_param(dev, "enable", 0); + return ret; +} + /** * pwmchip_add() - register a new pwm * @chip: the pwm @@ -52,7 +122,7 @@ static struct pwm_device *_find_pwm(const char *devname) * register a new pwm. pwm->devname must be initialized, usually * from dev_name(dev) from the hardware driver. */ -int pwmchip_add(struct pwm_chip *chip) +int pwmchip_add(struct pwm_chip *chip, struct device_d *dev) { struct pwm_device *pwm; int ret = 0; @@ -62,8 +132,10 @@ int pwmchip_add(struct pwm_chip *chip) pwm = xzalloc(sizeof(*pwm)); pwm->chip = chip; + pwm->dev = dev; list_add_tail(&pwm->node, &pwm_list); + pwm_register_vars(dev); return ret; } @@ -136,6 +208,8 @@ EXPORT_SYMBOL_GPL(pwm_free); */ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) { + pwm->chip->duty_ns = duty_ns; + pwm->chip->period_ns = period_ns; return pwm->chip->ops->config(pwm->chip, duty_ns, period_ns); } EXPORT_SYMBOL_GPL(pwm_config); diff --git a/include/pwm.h b/include/pwm.h index 80f88b1..bdc2fdd 100644 --- a/include/pwm.h +++ b/include/pwm.h @@ -2,6 +2,7 @@ #define __PWM_H struct pwm_device; +struct device_d; /* * pwm_request - request a PWM device @@ -51,13 +52,17 @@ struct pwm_ops { * struct pwm_chip - abstract a PWM * @devname: unique identifier for this pwm * @ops: The callbacks for this PWM + * @duty_ns: The duty cycle of the PWM, in nano-seconds + * @period_ns: The period of the PWM, in nano-seconds */ struct pwm_chip { const char *devname; struct pwm_ops *ops; + int duty_ns; + int period_ns; }; -int pwmchip_add(struct pwm_chip *chip); +int pwmchip_add(struct pwm_chip *chip, struct device_d *dev); int pwmchip_remove(struct pwm_chip *chip); #endif /* __PWM_H */ -- 1.7.5.4 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH V3 2/3] drivers/pwm: add PXA pulse width modulator controller 2012-02-16 18:23 ` [PATCH V3 1/3] drivers/pwm: add duty_ns and period_ns to core pwm chip Robert Jarzmik @ 2012-02-16 18:23 ` Robert Jarzmik 2012-02-16 18:23 ` [PATCH V3 3/3] drivers/video: remove pxafb enable on load Robert Jarzmik 1 sibling, 0 replies; 19+ messages in thread From: Robert Jarzmik @ 2012-02-16 18:23 UTC (permalink / raw) To: barebox Add PXA embedded pulse width modulator support. The PWM can generate signals from 49.6kHz to 1.625MHz. The driver is for pxa2xx family. The pxa3xx was not handled yet. Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr> --- arch/arm/mach-pxa/Makefile | 1 + arch/arm/mach-pxa/devices.c | 5 + arch/arm/mach-pxa/include/mach/clock.h | 1 + arch/arm/mach-pxa/include/mach/devices.h | 2 +- arch/arm/mach-pxa/include/mach/regs-pwm.h | 20 ++++ arch/arm/mach-pxa/speed-pxa27x.c | 5 + drivers/pwm/Kconfig | 6 + drivers/pwm/Makefile | 1 + drivers/pwm/pxa_pwm.c | 157 +++++++++++++++++++++++++++++ 9 files changed, 197 insertions(+), 1 deletions(-) create mode 100644 arch/arm/mach-pxa/include/mach/regs-pwm.h create mode 100644 drivers/pwm/pxa_pwm.c diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index c01a9e0..6a02a54 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -1,6 +1,7 @@ obj-y += clocksource.o obj-y += common.o obj-y += gpio.o +obj-y += devices.o obj-$(CONFIG_ARCH_PXA2XX) += mfp-pxa2xx.o obj-$(CONFIG_ARCH_PXA27X) += speed-pxa27x.o diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index 1a396f1..b6ac0ba 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c @@ -47,3 +47,8 @@ struct device_d *pxa_add_mmc(void *base, int id, void *pdata) { return pxa_add_device("pxa-mmc", id, base, 0x1000, pdata); } + +struct device_d *pxa_add_pwm(void *base, int id) +{ + return pxa_add_device("pxa_pwm", id, base, 0x10, NULL); +} diff --git a/arch/arm/mach-pxa/include/mach/clock.h b/arch/arm/mach-pxa/include/mach/clock.h index c53432f..f86152f 100644 --- a/arch/arm/mach-pxa/include/mach/clock.h +++ b/arch/arm/mach-pxa/include/mach/clock.h @@ -14,5 +14,6 @@ unsigned long pxa_get_uartclk(void); unsigned long pxa_get_mmcclk(void); unsigned long pxa_get_lcdclk(void); +unsigned long pxa_get_pwmclk(void); #endif /* !__MACH_CLOCK_H */ diff --git a/arch/arm/mach-pxa/include/mach/devices.h b/arch/arm/mach-pxa/include/mach/devices.h index e205b7c..8390153 100644 --- a/arch/arm/mach-pxa/include/mach/devices.h +++ b/arch/arm/mach-pxa/include/mach/devices.h @@ -23,4 +23,4 @@ struct device_d *pxa_add_i2c(void *base, int id, struct device_d *pxa_add_uart(void *base, int id); struct device_d *pxa_add_fb(void *base, struct pxafb_platform_data *pdata); struct device_d *pxa_add_mmc(void *base, int id, void *pdata); - +struct device_d *pxa_add_pwm(void *base, int id); diff --git a/arch/arm/mach-pxa/include/mach/regs-pwm.h b/arch/arm/mach-pxa/include/mach/regs-pwm.h new file mode 100644 index 0000000..9fdcbb6 --- /dev/null +++ b/arch/arm/mach-pxa/include/mach/regs-pwm.h @@ -0,0 +1,20 @@ +/* + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __ASM_MACH_REGS_PWM_H +#define __ASM_MACH_REGS_PWM_H + +#include <mach/hardware.h> + +/* + * Pulse modulator registers + */ +#define PWM0 0x40B00000 +#define PWM1 0x40C00000 +#define PWM0slave 0x40B00010 +#define PWM1slave 0x40C00010 + +#endif diff --git a/arch/arm/mach-pxa/speed-pxa27x.c b/arch/arm/mach-pxa/speed-pxa27x.c index 534eb1d..1de034c 100644 --- a/arch/arm/mach-pxa/speed-pxa27x.c +++ b/arch/arm/mach-pxa/speed-pxa27x.c @@ -47,3 +47,8 @@ unsigned long pxa_get_lcdclk(void) { return pxa_get_lcdclk_10khz() * 10000; } + +unsigned long pxa_get_pwmclk(void) +{ + return BASE_CLK; +} diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig index 93c1052..50c956a 100644 --- a/drivers/pwm/Kconfig +++ b/drivers/pwm/Kconfig @@ -8,5 +8,11 @@ menuconfig PWM If unsure, say N. if PWM +config PWM_PXA + bool "PXA PWM Support" + default y if ARCH_PXA2XX + help + This enables PWM support for Intel/Marvell PXA chips, such + as the PXA25x, PXA27x. endif diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile index 3469c3d..c886bd5 100644 --- a/drivers/pwm/Makefile +++ b/drivers/pwm/Makefile @@ -1 +1,2 @@ obj-$(CONFIG_PWM) += core.o +obj-$(CONFIG_PWM_PXA) += pxa_pwm.o \ No newline at end of file diff --git a/drivers/pwm/pxa_pwm.c b/drivers/pwm/pxa_pwm.c new file mode 100644 index 0000000..cf1f96a --- /dev/null +++ b/drivers/pwm/pxa_pwm.c @@ -0,0 +1,157 @@ +/* + * simple driver for PWM (Pulse Width Modulator) controller + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 2008-02-13 initial version eric miao <eric.miao@marvell.com> + * 2012 Robert Jarzmik <robert.jarzmik@free.fr> + */ + +#include <common.h> +#include <init.h> +#include <errno.h> +#include <io.h> +#include <pwm.h> + +#include <mach/hardware.h> +#include <mach/clock.h> +#include <mach/pxa-regs.h> +#include <mach/regs-pwm.h> +#include <asm-generic/div64.h> +#include <linux/compiler.h> + +/* PWM registers and bits definitions */ +#define PWMCR (0x00) +#define PWMDCR (0x04) +#define PWMPCR (0x08) + +#define PWMCR_SD (1 << 6) +#define PWMDCR_FD (1 << 10) + +struct pxa_pwm_chip { + struct pwm_chip chip; + void __iomem *iobase; + int id; + int duty_ns; + int period_ns; +}; + +static struct pxa_pwm_chip *to_pxa_pwm_chip(struct pwm_chip *chip) +{ + return container_of(chip, struct pxa_pwm_chip, chip); +} + +/* + * period_ns = 10^9 * (PRESCALE + 1) * (PV + 1) / PWM_CLK_RATE + * duty_ns = 10^9 * (PRESCALE + 1) * DC / PWM_CLK_RATE + * PWM_CLK_RATE = 13 MHz + */ +static int pxa_pwm_config(struct pwm_chip *chip, int duty_ns, int period_ns) +{ + unsigned long long c; + unsigned long period_cycles, prescale, pv, dc; + struct pxa_pwm_chip *pxa_pwm = to_pxa_pwm_chip(chip); + + c = pxa_get_pwmclk(); + c = c * period_ns; + do_div(c, 1000000000); + period_cycles = c; + + if (period_cycles < 1) + period_cycles = 1; + prescale = (period_cycles - 1) / 1024; + pv = period_cycles / (prescale + 1) - 1; + + if (prescale > 63) + return -EINVAL; + + if (duty_ns == period_ns) + dc = PWMDCR_FD; + else + dc = (pv + 1) * duty_ns / period_ns; + + pxa_pwm->duty_ns = duty_ns; + pxa_pwm->period_ns = period_ns; + + /* NOTE: the clock to PWM has to be enabled first + * before writing to the registers + */ + __raw_writel(prescale, pxa_pwm->iobase + PWMCR); + __raw_writel(dc, pxa_pwm->iobase + PWMDCR); + __raw_writel(pv, pxa_pwm->iobase + PWMPCR); + + return 0; +} + +static int pxa_pwm_enable(struct pwm_chip *chip) +{ + struct pxa_pwm_chip *pxa_pwm = to_pxa_pwm_chip(chip); + + switch (pxa_pwm->id) { + case 0: + case 2: + CKEN |= CKEN_PWM0; + break; + case 1: + case 3: + CKEN |= CKEN_PWM1; + break; + default: + return -EINVAL; + } + return 0; +} + +static void pxa_pwm_disable(struct pwm_chip *chip) +{ + struct pxa_pwm_chip *pxa_pwm = to_pxa_pwm_chip(chip); + + switch (pxa_pwm->id) { + case 0: + case 2: + CKEN &= ~CKEN_PWM0; + break; + case 1: + case 3: + CKEN &= ~CKEN_PWM1; + break; + default: + break; + } +} + +static struct pwm_ops pxa_pwm_ops = { + .config = pxa_pwm_config, + .enable = pxa_pwm_enable, + .disable = pxa_pwm_disable, +}; + +static int pxa_pwm_probe(struct device_d *dev) +{ + struct pxa_pwm_chip *chip; + + chip = xzalloc(sizeof(*chip)); + chip->chip.devname = asprintf("%s", dev_name(dev)); + chip->chip.ops = &pxa_pwm_ops; + chip->iobase = dev_request_mem_region(dev, 0); + chip->id = dev->id; + dev->priv = chip; + + return pwmchip_add(&chip->chip, dev); +} + +static struct driver_d pxa_pwm_driver = { + .name = "pxa_pwm", + .probe = pxa_pwm_probe, +}; + +static int __init pxa_pwm_init_driver(void) +{ + CKEN &= ~CKEN_PWM0 & ~CKEN_PWM1; + register_driver(&pxa_pwm_driver); + return 0; +} + +device_initcall(pxa_pwm_init_driver); -- 1.7.5.4 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH V3 3/3] drivers/video: remove pxafb enable on load 2012-02-16 18:23 ` [PATCH V3 1/3] drivers/pwm: add duty_ns and period_ns to core pwm chip Robert Jarzmik 2012-02-16 18:23 ` [PATCH V3 2/3] drivers/pwm: add PXA pulse width modulator controller Robert Jarzmik @ 2012-02-16 18:23 ` Robert Jarzmik 1 sibling, 0 replies; 19+ messages in thread From: Robert Jarzmik @ 2012-02-16 18:23 UTC (permalink / raw) To: barebox As pxafb can rely on a PWM to control backlight, and because driver dependencies are hard to deal with, remove automatic enable of PXAFB on probe. The user should in its environment do a : - fb0.enable=1 This way, the PWM has been probed and is ready to work, and the pxafb backlight control works. Signed-off-by: Robert Jarzmik <robert.jarzmik@free.fr> --- arch/arm/mach-pxa/include/mach/pxafb.h | 1 - drivers/video/pxa.c | 3 --- 2 files changed, 0 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-pxa/include/mach/pxafb.h b/arch/arm/mach-pxa/include/mach/pxafb.h index 1730fbf..23cbea9 100644 --- a/arch/arm/mach-pxa/include/mach/pxafb.h +++ b/arch/arm/mach-pxa/include/mach/pxafb.h @@ -64,7 +64,6 @@ struct pxafb_videomode { struct pxafb_platform_data { struct pxafb_videomode *mode; unsigned int lcd_conn; - int enable_on_load; /** force a memory area to be used, else NULL for dynamic allocation */ void *framebuffer; diff --git a/drivers/video/pxa.c b/drivers/video/pxa.c index ddd7087..900ae80 100644 --- a/drivers/video/pxa.c +++ b/drivers/video/pxa.c @@ -538,9 +538,6 @@ static int pxafb_probe(struct device_d *dev) return ret; } - if (pdata->enable_on_load) - info->fbops->fb_enable(info); - return 0; } -- 1.7.5.4 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2012-02-16 18:24 UTC | newest] Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2012-01-31 9:36 [PATCH] Add pwm core support Sascha Hauer 2012-02-01 8:20 ` Robert Jarzmik 2012-02-01 22:42 ` [PATCH] drivers/pwm: add PXA pulse width modulator controller Robert Jarzmik 2012-02-03 9:52 ` Sascha Hauer 2012-02-03 15:39 ` Robert Jarzmik 2012-02-08 15:26 ` Robert Jarzmik 2012-02-09 8:10 ` Sascha Hauer 2012-02-09 11:50 ` Robert Jarzmik 2012-02-09 13:44 ` Sascha Hauer 2012-02-09 14:30 ` Robert Jarzmik 2012-02-14 12:58 ` [PATCH V2 1/2] " Robert Jarzmik 2012-02-14 12:58 ` [PATCH V2 2/2] drivers/video: remove pxafb enable on load Robert Jarzmik 2012-02-15 8:32 ` [PATCH V2 1/2] drivers/pwm: add PXA pulse width modulator controller Sascha Hauer 2012-02-15 11:22 ` Robert Jarzmik 2012-02-15 15:21 ` Robert Jarzmik 2012-02-16 7:40 ` Sascha Hauer 2012-02-16 18:23 ` [PATCH V3 1/3] drivers/pwm: add duty_ns and period_ns to core pwm chip Robert Jarzmik 2012-02-16 18:23 ` [PATCH V3 2/3] drivers/pwm: add PXA pulse width modulator controller Robert Jarzmik 2012-02-16 18:23 ` [PATCH V3 3/3] drivers/video: remove pxafb enable on load Robert Jarzmik
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox