Hi,
This patch set swtiches the at91 and avr32 SoCs and board to the generic PWM
framework. This allows to remove the obsolete leds-atmel-pwm, atmel-pwm-bl and
atmel_pwm drivers.
The first 6 patches take care of the AT91 boards and removes a useless function
in the process.
Patch 7 makes pwm-ateml buildable for AVR32
Patch 8 allows setting the pwm polarity for pwm_bl when using platform data.
This is required afterwards for the favr-32
Patches 9-13 take care of the AVR32 boards. This has only been compile tested as
I don't own any of those boards.
And the last 3 patches are removing the now obsolete drivers.
As a note, the atmel_pwm driver has two features not yet available through
pwm-atmel:
- it is possible to pass an IRQ handler that will get called each time one of
the channel period has been acheived.
- it was possible to set clka and clkb, two clock that divided mck before
feeding the pwm controller.
Those features are not used by anything in the mainline. I'm not sure we can
implement the first one. We'll get back the second one once all the boards have
swtiched to the common clock framework.
Alexandre Belloni (16):
ARM: at91: at91sam9g45: switch to generic PWM framework
ARM: at91: sam9m10g45ek: use generic leds_pwm driver
ARM: at91: at91sam9263: switch to generic PWM framework
ARM: at91: sam9263ek: use generic leds_pwm driver
ARM: at91: at91sam9rl: switch to generic PWM framework
ARM: at91: remove useless at91_pwm_leds()
PWM: atmel: allow building for AVR32
backlight: pwm_bl: set pwm polarity when using platform data
avr32/at32ap: switch to the generic PWM framework
avr32: MRMT: use generic leds_pwm driver
avr32: merisc: use generic leds_pwm driver
avr32: favr-32: use generic pwm_bl driver
avr32: update defconfig to use the generic PWM framework
backlight: atmel-pwm-bl: remove obsolete driver
leds: atmel-pwm: remove obsolete driver
misc: atmel_pwm: remove obsolete driver
arch/arm/mach-at91/at91sam9263.c | 1 +
arch/arm/mach-at91/at91sam9263_devices.c | 11 +-
arch/arm/mach-at91/at91sam9g45.c | 1 +
arch/arm/mach-at91/at91sam9g45_devices.c | 11 +-
arch/arm/mach-at91/at91sam9rl.c | 1 +
arch/arm/mach-at91/at91sam9rl_devices.c | 11 +-
arch/arm/mach-at91/board-sam9263ek.c | 56 +++-
arch/arm/mach-at91/board-sam9m10g45ek.c | 43 ++-
arch/arm/mach-at91/board.h | 1 -
arch/arm/mach-at91/leds.c | 37 ---
arch/avr32/boards/atngw100/mrmt.c | 35 ++-
arch/avr32/boards/favr-32/setup.c | 49 ++--
arch/avr32/boards/merisc/setup.c | 34 ++-
arch/avr32/configs/atngw100_mrmt_defconfig | 5 +-
arch/avr32/configs/atstk1002_defconfig | 5 +-
arch/avr32/configs/atstk1003_defconfig | 5 +-
arch/avr32/configs/atstk1004_defconfig | 5 +-
arch/avr32/configs/atstk1006_defconfig | 5 +-
arch/avr32/configs/favr-32_defconfig | 6 +-
arch/avr32/configs/merisc_defconfig | 5 +-
arch/avr32/mach-at32ap/at32ap700x.c | 7 +-
drivers/leds/Kconfig | 8 -
drivers/leds/Makefile | 1 -
drivers/leds/leds-atmel-pwm.c | 149 -----------
drivers/misc/Kconfig | 9 -
drivers/misc/Makefile | 1 -
drivers/misc/atmel_pwm.c | 402 -----------------------------
drivers/pwm/Kconfig | 2 +-
drivers/video/backlight/Kconfig | 11 -
drivers/video/backlight/Makefile | 1 -
drivers/video/backlight/atmel-pwm-bl.c | 223 ----------------
drivers/video/backlight/pwm_bl.c | 8 +
include/linux/atmel-pwm-bl.h | 43 ---
include/linux/atmel_pwm.h | 70 -----
include/linux/pwm_backlight.h | 1 +
35 files changed, 199 insertions(+), 1064 deletions(-)
delete mode 100644 drivers/leds/leds-atmel-pwm.c
delete mode 100644 drivers/misc/atmel_pwm.c
delete mode 100644 drivers/video/backlight/atmel-pwm-bl.c
delete mode 100644 include/linux/atmel-pwm-bl.h
delete mode 100644 include/linux/atmel_pwm.h
--
1.8.3.2
Now that all at91 boards using leds-atmel-pwm switched to leds-pwm, the
at91_pwm_leds() function is not used anymore.
Signed-off-by: Alexandre Belloni <redacted>
---
arch/arm/mach-at91/board.h | 1 -
arch/arm/mach-at91/leds.c | 37 -------------------------------------
2 files changed, 38 deletions(-)
@@ -155,21 +157,29 @@ static struct platform_device rmt_ts_device = {#ifdef CONFIG_BOARD_MRMT_BL_PWM/* PWM LEDs: LCD Backlight, etc */-staticstructgpio_ledrmt_pwm_led[]={-/* here the "gpio" is actually a PWM channel */-{.name="backlight",.gpio=PWM_CH_BL,},+staticstructpwm_lookuppwm_lookup[]={+PWM_LOOKUP("at91sam9rl-pwm",PWM_CH_BL,"leds_pwm","ds1"),};-staticstructgpio_led_platform_datarmt_pwm_led_data={-.num_leds=ARRAY_SIZE(rmt_pwm_led),-.leds=rmt_pwm_led,+staticstructled_pwmpwm_leds[]={+{+.name="backlight",+.max_brightness=255,+.pwm_period_ns=5000,+.active_low=1,+},+};++staticstructled_pwm_platform_datapwm_data={+.num_leds=ARRAY_SIZE(pwm_leds),+.leds=pwm_leds,};-staticstructplatform_devicermt_pwm_led_dev={-.name="leds-atmel-pwm",-.id=-1,-.dev={-.platform_data=&rmt_pwm_led_data,+staticstructplatform_deviceleds_pwm={+.name="leds_pwm",+.id=-1,+.dev={+.platform_data=&pwm_data,},};#endif
@@ -325,7 +335,8 @@ static int __init mrmt1_init(void)#ifdef CONFIG_BOARD_MRMT_BL_PWM/* Use PWM for Backlight controls */at32_add_device_pwm(1<<PWM_CH_BL);-platform_device_register(&rmt_pwm_led_dev);+pwm_add_table(pwm_lookup,ARRAY_SIZE(pwm_lookup));+platform_device_register(&leds_pwm);#else/* Backlight always on */udelay(1);
The misc/atmel_pwm is not used by any mainlined boards and has been replaced by
the pwm-driver using the generic PWM framework.
Signed-off-by: Alexandre Belloni <redacted>
---
drivers/misc/Kconfig | 9 --
drivers/misc/Makefile | 1 -
drivers/misc/atmel_pwm.c | 402 ----------------------------------------------
include/linux/atmel_pwm.h | 70 --------
4 files changed, 482 deletions(-)
delete mode 100644 drivers/misc/atmel_pwm.c
delete mode 100644 include/linux/atmel_pwm.h
@@ -1,70 +0,0 @@-#ifndef __LINUX_ATMEL_PWM_H-#define __LINUX_ATMEL_PWM_H--/**- * struct pwm_channel - driver handle to a PWM channel- * @regs: base of this channel's registers- * @index: number of this channel (0..31)- * @mck: base clock rate, which can be prescaled and maybe subdivided- *- * Drivers initialize a pwm_channel structure using pwm_channel_alloc().- * Then they configure its clock rate (derived from MCK), alignment,- * polarity, and duty cycle by writing directly to the channel registers,- * before enabling the channel by calling pwm_channel_enable().- *- * After emitting a PWM signal for the desired length of time, drivers- * may then pwm_channel_disable() or pwm_channel_free(). Both of these- * disable the channel, but when it's freed the IRQ is deconfigured and- * the channel must later be re-allocated and reconfigured.- *- * Note that if the period or duty cycle need to be changed while the- * PWM channel is operating, drivers must use the PWM_CUPD double buffer- * mechanism, either polling until they change or getting implicitly- * notified through a once-per-period interrupt handler.- */-struct pwm_channel {- void __iomem *regs;- unsigned index;- unsigned long mck;-};--extern int pwm_channel_alloc(int index, struct pwm_channel *ch);-extern int pwm_channel_free(struct pwm_channel *ch);--extern int pwm_clk_alloc(unsigned prescale, unsigned div);-extern void pwm_clk_free(unsigned clk);--extern int __pwm_channel_onoff(struct pwm_channel *ch, int enabled);--#define pwm_channel_enable(ch) __pwm_channel_onoff((ch), 1)-#define pwm_channel_disable(ch) __pwm_channel_onoff((ch), 0)--/* periodic interrupts, mostly for CUPD changes to period or cycle */-extern int pwm_channel_handler(struct pwm_channel *ch,- void (*handler)(struct pwm_channel *ch));--/* per-channel registers (banked at pwm_channel->regs) */-#define PWM_CMR 0x00 /* mode register */-#define PWM_CPR_CPD (1 << 10) /* set: CUPD modifies period */-#define PWM_CPR_CPOL (1 << 9) /* set: idle high */-#define PWM_CPR_CALG (1 << 8) /* set: center align */-#define PWM_CPR_CPRE (0xf << 0) /* mask: rate is mck/(2^pre) */-#define PWM_CPR_CLKA (0xb << 0) /* rate CLKA */-#define PWM_CPR_CLKB (0xc << 0) /* rate CLKB */-#define PWM_CDTY 0x04 /* duty cycle (max of CPRD) */-#define PWM_CPRD 0x08 /* period (count up from zero) */-#define PWM_CCNT 0x0c /* counter (20 bits?) */-#define PWM_CUPD 0x10 /* update CPRD (or CDTY) next period */--static inline void-pwm_channel_writel(struct pwm_channel *pwmc, unsigned offset, u32 val)-{- __raw_writel(val, pwmc->regs + offset);-}--static inline u32 pwm_channel_readl(struct pwm_channel *pwmc, unsigned offset)-{- return __raw_readl(pwmc->regs + offset);-}--#endif /* __LINUX_ATMEL_PWM_H */
The leds-atmel-pwmdriver is now obsolete. It is not used by any mainlined boards
and is replaced by the generic leds_pwm with the pawm-atmel driver using the
generic PWM framework.
Signed-off-by: Alexandre Belloni <redacted>
---
drivers/leds/Kconfig | 8 ---
drivers/leds/Makefile | 1 -
drivers/leds/leds-atmel-pwm.c | 149 ------------------------------------------
3 files changed, 158 deletions(-)
delete mode 100644 drivers/leds/leds-atmel-pwm.c
@@ -1,149 +0,0 @@-#include <linux/kernel.h>-#include <linux/platform_device.h>-#include <linux/leds.h>-#include <linux/io.h>-#include <linux/atmel_pwm.h>-#include <linux/slab.h>-#include <linux/module.h>---struct pwmled {- struct led_classdev cdev;- struct pwm_channel pwmc;- struct gpio_led *desc;- u32 mult;- u8 active_low;-};---/*- * For simplicity, we use "brightness" as if it were a linear function- * of PWM duty cycle. However, a logarithmic function of duty cycle is- * probably a better match for perceived brightness: two is half as bright- * as four, four is half as bright as eight, etc- */-static void pwmled_brightness(struct led_classdev *cdev, enum led_brightness b)-{- struct pwmled *led;-- /* update the duty cycle for the *next* period */- led = container_of(cdev, struct pwmled, cdev);- pwm_channel_writel(&led->pwmc, PWM_CUPD, led->mult * (unsigned) b);-}--/*- * NOTE: we reuse the platform_data structure of GPIO leds,- * but repurpose its "gpio" number as a PWM channel number.- */-static int pwmled_probe(struct platform_device *pdev)-{- const struct gpio_led_platform_data *pdata;- struct pwmled *leds;- int i;- int status;-- pdata = dev_get_platdata(&pdev->dev);- if (!pdata || pdata->num_leds < 1)- return -ENODEV;-- leds = devm_kzalloc(&pdev->dev, pdata->num_leds * sizeof(*leds),- GFP_KERNEL);- if (!leds)- return -ENOMEM;-- for (i = 0; i < pdata->num_leds; i++) {- struct pwmled *led = leds + i;- const struct gpio_led *dat = pdata->leds + i;- u32 tmp;-- led->cdev.name = dat->name;- led->cdev.brightness = LED_OFF;- led->cdev.brightness_set = pwmled_brightness;- led->cdev.default_trigger = dat->default_trigger;-- led->active_low = dat->active_low;-- status = pwm_channel_alloc(dat->gpio, &led->pwmc);- if (status < 0)- goto err;-- /*- * Prescale clock by 2^x, so PWM counts in low MHz.- * Start each cycle with the LED active, so increasing- * the duty cycle gives us more time on (= brighter).- */- tmp = 5;- if (!led->active_low)- tmp |= PWM_CPR_CPOL;- pwm_channel_writel(&led->pwmc, PWM_CMR, tmp);-- /*- * Pick a period so PWM cycles at 100+ Hz; and a multiplier- * for scaling duty cycle: brightness * mult.- */- tmp = (led->pwmc.mck / (1 << 5)) / 100;- tmp /= 255;- led->mult = tmp;- pwm_channel_writel(&led->pwmc, PWM_CDTY,- led->cdev.brightness * 255);- pwm_channel_writel(&led->pwmc, PWM_CPRD,- LED_FULL * tmp);-- pwm_channel_enable(&led->pwmc);-- /* Hand it over to the LED framework */- status = led_classdev_register(&pdev->dev, &led->cdev);- if (status < 0) {- pwm_channel_free(&led->pwmc);- goto err;- }- }-- platform_set_drvdata(pdev, leds);- return 0;--err:- if (i > 0) {- for (i = i - 1; i >= 0; i--) {- led_classdev_unregister(&leds[i].cdev);- pwm_channel_free(&leds[i].pwmc);- }- }-- return status;-}--static int pwmled_remove(struct platform_device *pdev)-{- const struct gpio_led_platform_data *pdata;- struct pwmled *leds;- unsigned i;-- pdata = dev_get_platdata(&pdev->dev);- leds = platform_get_drvdata(pdev);-- for (i = 0; i < pdata->num_leds; i++) {- struct pwmled *led = leds + i;-- led_classdev_unregister(&led->cdev);- pwm_channel_free(&led->pwmc);- }-- return 0;-}--static struct platform_driver pwmled_driver = {- .driver = {- .name = "leds-atmel-pwm",- .owner = THIS_MODULE,- },- /* REVISIT add suspend() and resume() methods */- .probe = pwmled_probe,- .remove = pwmled_remove,-};--module_platform_driver(pwmled_driver);--MODULE_DESCRIPTION("Driver for LEDs with PWM-controlled brightness");-MODULE_LICENSE("GPL");-MODULE_ALIAS("platform:leds-atmel-pwm");
The atmel-pwm-bl driver is now obsolete. It is not used by any mainlined boards
and is replaced by the generic pwm_bl with the pawm-atmel driver using the
generic PWM framework.
Signed-off-by: Alexandre Belloni <redacted>
---
drivers/video/backlight/Kconfig | 11 --
drivers/video/backlight/Makefile | 1 -
drivers/video/backlight/atmel-pwm-bl.c | 223 ---------------------------------
include/linux/atmel-pwm-bl.h | 43 -------
4 files changed, 278 deletions(-)
delete mode 100644 drivers/video/backlight/atmel-pwm-bl.c
delete mode 100644 include/linux/atmel-pwm-bl.h
@@ -1,43 +0,0 @@-/*- * Copyright (C) 2007 Atmel Corporation- *- * Driver for the AT32AP700X PS/2 controller (PSIF).- *- * 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 __INCLUDE_ATMEL_PWM_BL_H-#define __INCLUDE_ATMEL_PWM_BL_H--/**- * struct atmel_pwm_bl_platform_data- * @pwm_channel: which PWM channel in the PWM module to use.- * @pwm_frequency: PWM frequency to generate, the driver will try to be as- * close as the prescaler allows.- * @pwm_compare_max: value to use in the PWM channel compare register.- * @pwm_duty_max: maximum duty cycle value, must be less than or equal to- * pwm_compare_max.- * @pwm_duty_min: minimum duty cycle value, must be less than pwm_duty_max.- * @pwm_active_low: set to one if the low part of the PWM signal increases the- * brightness of the backlight.- * @gpio_on: GPIO line to control the backlight on/off, set to -1 if not used.- * @on_active_low: set to one if the on/off signal is on when GPIO is low.- *- * This struct must be added to the platform device in the board code. It is- * used by the atmel-pwm-bl driver to setup the GPIO to control on/off and the- * PWM device.- */-struct atmel_pwm_bl_platform_data {- unsigned int pwm_channel;- unsigned int pwm_frequency;- unsigned int pwm_compare_max;- unsigned int pwm_duty_max;- unsigned int pwm_duty_min;- unsigned int pwm_active_low;- int gpio_on;- unsigned int on_active_low;-};--#endif /* __INCLUDE_ATMEL_PWM_BL_H */
@@ -64,7 +64,6 @@ CONFIG_BLK_DEV_LOOP=m CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=m CONFIG_MISC_DEVICES=y-CONFIG_ATMEL_PWM=m CONFIG_ATMEL_TCLIB=y CONFIG_ATMEL_SSC=m # CONFIG_SCSI_PROC_FS is not set
@@ -133,14 +132,16 @@ CONFIG_MMC_TEST=m CONFIG_MMC_ATMELMCI=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y-CONFIG_LEDS_ATMEL_PWM=m CONFIG_LEDS_GPIO=m+CONFIG_LEDS_PWM=m CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=m CONFIG_LEDS_TRIGGER_HEARTBEAT=m CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_AT32AP700X=y CONFIG_DMADEVICES=y+CONFIG_PWM=y+CONFIG_PWM_ATMEL=m CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
@@ -53,7 +53,6 @@ CONFIG_BLK_DEV_LOOP=m CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=m CONFIG_MISC_DEVICES=y-CONFIG_ATMEL_PWM=m CONFIG_ATMEL_TCLIB=y CONFIG_ATMEL_SSC=m # CONFIG_SCSI_PROC_FS is not set
@@ -112,14 +111,16 @@ CONFIG_MMC_TEST=m CONFIG_MMC_ATMELMCI=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y-CONFIG_LEDS_ATMEL_PWM=m CONFIG_LEDS_GPIO=m+CONFIG_LEDS_PWM=m CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=m CONFIG_LEDS_TRIGGER_HEARTBEAT=m CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_AT32AP700X=y CONFIG_DMADEVICES=y+CONFIG_PWM=y+CONFIG_PWM_ATMEL=m CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
@@ -53,7 +53,6 @@ CONFIG_BLK_DEV_LOOP=m CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=m CONFIG_MISC_DEVICES=y-CONFIG_ATMEL_PWM=m CONFIG_ATMEL_TCLIB=y CONFIG_ATMEL_SSC=m # CONFIG_SCSI_PROC_FS is not set
@@ -111,14 +110,16 @@ CONFIG_MMC_TEST=m CONFIG_MMC_ATMELMCI=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y-CONFIG_LEDS_ATMEL_PWM=m CONFIG_LEDS_GPIO=m+CONFIG_LEDS_PWM=m CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=m CONFIG_LEDS_TRIGGER_HEARTBEAT=m CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_AT32AP700X=y CONFIG_DMADEVICES=y+CONFIG_PWM=y+CONFIG_PWM_ATMEL=m CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
@@ -67,7 +67,6 @@ CONFIG_BLK_DEV_LOOP=m CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=m CONFIG_MISC_DEVICES=y-CONFIG_ATMEL_PWM=m CONFIG_ATMEL_TCLIB=y CONFIG_ATMEL_SSC=m # CONFIG_SCSI_PROC_FS is not set
@@ -136,14 +135,16 @@ CONFIG_MMC_TEST=m CONFIG_MMC_ATMELMCI=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y-CONFIG_LEDS_ATMEL_PWM=m CONFIG_LEDS_GPIO=m+CONFIG_LEDS_PWM=m CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_TIMER=m CONFIG_LEDS_TRIGGER_HEARTBEAT=m CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_AT32AP700X=y CONFIG_DMADEVICES=y+CONFIG_PWM=y+CONFIG_PWM_ATMEL=m CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
@@ -103,12 +102,14 @@ CONFIG_MMC=y CONFIG_MMC_ATMELMCI=y CONFIG_NEW_LEDS=y CONFIG_LEDS_CLASS=y-CONFIG_LEDS_ATMEL_PWM=y+CONFIG_LEDS_PWM=y CONFIG_RTC_CLASS=y # CONFIG_RTC_HCTOSYS is not set CONFIG_RTC_DRV_PCF8563=y CONFIG_DMADEVICES=y CONFIG_UIO=y+CONFIG_PWM=y+CONFIG_PWM_ATMEL=m CONFIG_EXT2_FS=y # CONFIG_DNOTIFY is not set CONFIG_FUSE_FS=y
@@ -108,7 +107,7 @@ CONFIG_FB=y CONFIG_FB_ATMEL=y CONFIG_BACKLIGHT_LCD_SUPPORT=y # CONFIG_LCD_CLASS_DEVICE is not set-CONFIG_BACKLIGHT_ATMEL_PWM=m+CONFIG_BACKLIGHT_PWM=m CONFIG_SOUND=m CONFIG_SOUND_PRIME=m # CONFIG_HID_SUPPORT is not set
@@ -132,6 +130,8 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_AT32AP700X=y CONFIG_DMADEVICES=y+CONFIG_PWM=y+CONFIG_PWM_ATMEL=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_FS_XATTR is not set
Set inversed polarity when .pwm_active_low is set in the platform_data. With
device tree, this is taken care of by of_pwm_xlate_with_flags(), called from
of_pwm_get().
Signed-off-by: Alexandre Belloni <redacted>
---
drivers/video/backlight/pwm_bl.c | 8 ++++++++
include/linux/pwm_backlight.h | 1 +
2 files changed, 9 insertions(+)
The Atmel PWM IP can be found on avr32 chips. This allows selecting and building
the driver on avr32.
Signed-off-by: Alexandre Belloni <redacted>
---
drivers/pwm/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
@@ -368,21 +370,48 @@ static struct gpio_led ek_leds[] = {.name="ds3",.gpio=AT91_PIN_PB7,.default_trigger="heartbeat",+},+#if !IS_ENABLED(CONFIG_LEDS_PWM)+{+.name="ds1",+.gpio=AT91_PIN_PB8,+.active_low=1,+.default_trigger="none",}+#endif};/**PWMLeds*/-staticstructgpio_ledek_pwm_led[]={-/* For now only DS1 is PWM-driven (by pwm1) */+staticstructpwm_lookuppwm_lookup[]={+PWM_LOOKUP("at91sam9rl-pwm",1,"leds_pwm","ds1"),+};++#if IS_ENABLED(CONFIG_LEDS_PWM)+staticstructled_pwmpwm_leds[]={{-.name="ds1",-.gpio=1,/* is PWM channel number */-.active_low=1,-.default_trigger="none",-}+.name="ds1",+.max_brightness=255,+.pwm_period_ns=5000,+.active_low=1,+},+};++staticstructled_pwm_platform_datapwm_data={+.num_leds=ARRAY_SIZE(pwm_leds),+.leds=pwm_leds,+};++staticstructplatform_deviceleds_pwm={+.name="leds_pwm",+.id=-1,+.dev={+.platform_data=&pwm_data,+},};+#endif+/**CAN
I found this a tiny bit weird, but found the matching instance in
drivers/pwm/pwm-atmel.c
IMHO it would initially have been better to call it atpwm_v1 or something
similar, more generic. But I guess that is too late to change at this point.
@@ -155,21 +157,29 @@ static struct platform_device rmt_ts_device = {#ifdef CONFIG_BOARD_MRMT_BL_PWM/* PWM LEDs: LCD Backlight, etc */-staticstructgpio_ledrmt_pwm_led[]={-/* here the "gpio" is actually a PWM channel */-{.name="backlight",.gpio=PWM_CH_BL,},+staticstructpwm_lookuppwm_lookup[]={+PWM_LOOKUP("at91sam9rl-pwm",PWM_CH_BL,"leds_pwm","ds1"),};-staticstructgpio_led_platform_datarmt_pwm_led_data={-.num_leds=ARRAY_SIZE(rmt_pwm_led),-.leds=rmt_pwm_led,+staticstructled_pwmpwm_leds[]={+{+.name="backlight",+.max_brightness=255,+.pwm_period_ns=5000,+.active_low=1,+},+};++staticstructled_pwm_platform_datapwm_data={+.num_leds=ARRAY_SIZE(pwm_leds),+.leds=pwm_leds,};-staticstructplatform_devicermt_pwm_led_dev={-.name="leds-atmel-pwm",-.id=-1,-.dev={-.platform_data=&rmt_pwm_led_data,+staticstructplatform_deviceleds_pwm={+.name="leds_pwm",+.id=-1,+.dev={+.platform_data=&pwm_data,},};#endif
@@ -325,7 +335,8 @@ static int __init mrmt1_init(void)#ifdef CONFIG_BOARD_MRMT_BL_PWM/* Use PWM for Backlight controls */at32_add_device_pwm(1<<PWM_CH_BL);-platform_device_register(&rmt_pwm_led_dev);+pwm_add_table(pwm_lookup,ARRAY_SIZE(pwm_lookup));+platform_device_register(&leds_pwm);#else/* Backlight always on */udelay(1);
@@ -108,7 +107,7 @@ CONFIG_FB=y CONFIG_FB_ATMEL=y CONFIG_BACKLIGHT_LCD_SUPPORT=y # CONFIG_LCD_CLASS_DEVICE is not set-CONFIG_BACKLIGHT_ATMEL_PWM=m+CONFIG_BACKLIGHT_PWM=m CONFIG_SOUND=m CONFIG_SOUND_PRIME=m # CONFIG_HID_SUPPORT is not set
@@ -132,6 +130,8 @@ CONFIG_LEDS_TRIGGER_DEFAULT_ON=y CONFIG_RTC_CLASS=y CONFIG_RTC_DRV_AT32AP700X=y CONFIG_DMADEVICES=y+CONFIG_PWM=y+CONFIG_PWM_ATMEL=y CONFIG_EXT2_FS=y CONFIG_EXT3_FS=y # CONFIG_EXT3_FS_XATTR is not set
Around Wed 19 Mar 2014 14:03:27 +0100 or thereabout, Alexandre Belloni wrote:
The atmel-pwm-bl driver is now obsolete. It is not used by any mainlined boards
and is replaced by the generic pwm_bl with the pawm-atmel driver using the
generic PWM framework.
Signed-off-by: Alexandre Belloni <redacted>
From: Jingoo Han <hidden> Date: 2014-03-21 00:51:27
On Wednesday, March 19, 2014 11:23 PM, Hans-Christian Egtvedt wrote:
Around Wed 19 Mar 2014 14:03:27 +0100 or thereabout, Alexandre Belloni wrote:
quoted
The atmel-pwm-bl driver is now obsolete. It is not used by any mainlined boards
and is replaced by the generic pwm_bl with the pawm-atmel driver using the
generic PWM framework.
Signed-off-by: Alexandre Belloni <redacted>
Acked-by: Hans-Christian Egtvedt <redacted>
Acked-by: Jingoo Han <redacted>
Best regards,
Jingoo Han
Hi,
On 21/03/2014 at 09:51:16 +0900, Jingoo Han wrote :
On Wednesday, March 19, 2014 11:23 PM, Hans-Christian Egtvedt wrote:
quoted
Around Wed 19 Mar 2014 14:03:27 +0100 or thereabout, Alexandre Belloni wrote:
quoted
The atmel-pwm-bl driver is now obsolete. It is not used by any mainlined boards
and is replaced by the generic pwm_bl with the pawm-atmel driver using the
generic PWM framework.
Signed-off-by: Alexandre Belloni <redacted>
Acked-by: Hans-Christian Egtvedt <redacted>
Acked-by: Jingoo Han <redacted>
You didn't comment on patch 08/16, are you fine with it ? I guess this
is the only one holding back the full series.
Regards,
--
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
From: Jingoo Han <hidden> Date: 2014-03-25 00:16:06
On Tuesday, March 25, 2014 12:54 AM, Alexandre Belloni wrote:
On 21/03/2014 at 09:51:16 +0900, Jingoo Han wrote :
quoted
On Wednesday, March 19, 2014 11:23 PM, Hans-Christian Egtvedt wrote:
quoted
Around Wed 19 Mar 2014 14:03:27 +0100 or thereabout, Alexandre Belloni wrote:
quoted
The atmel-pwm-bl driver is now obsolete. It is not used by any mainlined boards
and is replaced by the generic pwm_bl with the pawm-atmel driver using the
generic PWM framework.
Signed-off-by: Alexandre Belloni <redacted>
Acked-by: Hans-Christian Egtvedt <redacted>
Acked-by: Jingoo Han <redacted>
You didn't comment on patch 08/16, are you fine with it ? I guess this
is the only one holding back the full series.
'drivers/video/backlight/pwm_bl.c' is Thierry Reding's domain,
as follows.
PWM SUBSYSTEM
M: Thierry Reding [off-list ref]
L: linux-pwm@vger.kernel.org
S: Maintained
.....
F: drivers/video/backlight/pwm_bl.c
So, it is required to get Ack from Thierry Reding.
Best regards,
Jingoo Han
On Wed, Mar 19, 2014 at 6:03 AM, Alexandre Belloni
[off-list ref] wrote:
The leds-atmel-pwmdriver is now obsolete. It is not used by any mainlined boards
and is replaced by the generic leds_pwm with the pawm-atmel driver using the
generic PWM framework.
@@ -1,149 +0,0 @@-#include <linux/kernel.h>-#include <linux/platform_device.h>-#include <linux/leds.h>-#include <linux/io.h>-#include <linux/atmel_pwm.h>-#include <linux/slab.h>-#include <linux/module.h>---struct pwmled {- struct led_classdev cdev;- struct pwm_channel pwmc;- struct gpio_led *desc;- u32 mult;- u8 active_low;-};---/*- * For simplicity, we use "brightness" as if it were a linear function- * of PWM duty cycle. However, a logarithmic function of duty cycle is- * probably a better match for perceived brightness: two is half as bright- * as four, four is half as bright as eight, etc- */-static void pwmled_brightness(struct led_classdev *cdev, enum led_brightness b)-{- struct pwmled *led;-- /* update the duty cycle for the *next* period */- led = container_of(cdev, struct pwmled, cdev);- pwm_channel_writel(&led->pwmc, PWM_CUPD, led->mult * (unsigned) b);-}--/*- * NOTE: we reuse the platform_data structure of GPIO leds,- * but repurpose its "gpio" number as a PWM channel number.- */-static int pwmled_probe(struct platform_device *pdev)-{- const struct gpio_led_platform_data *pdata;- struct pwmled *leds;- int i;- int status;-- pdata = dev_get_platdata(&pdev->dev);- if (!pdata || pdata->num_leds < 1)- return -ENODEV;-- leds = devm_kzalloc(&pdev->dev, pdata->num_leds * sizeof(*leds),- GFP_KERNEL);- if (!leds)- return -ENOMEM;-- for (i = 0; i < pdata->num_leds; i++) {- struct pwmled *led = leds + i;- const struct gpio_led *dat = pdata->leds + i;- u32 tmp;-- led->cdev.name = dat->name;- led->cdev.brightness = LED_OFF;- led->cdev.brightness_set = pwmled_brightness;- led->cdev.default_trigger = dat->default_trigger;-- led->active_low = dat->active_low;-- status = pwm_channel_alloc(dat->gpio, &led->pwmc);- if (status < 0)- goto err;-- /*- * Prescale clock by 2^x, so PWM counts in low MHz.- * Start each cycle with the LED active, so increasing- * the duty cycle gives us more time on (= brighter).- */- tmp = 5;- if (!led->active_low)- tmp |= PWM_CPR_CPOL;- pwm_channel_writel(&led->pwmc, PWM_CMR, tmp);-- /*- * Pick a period so PWM cycles at 100+ Hz; and a multiplier- * for scaling duty cycle: brightness * mult.- */- tmp = (led->pwmc.mck / (1 << 5)) / 100;- tmp /= 255;- led->mult = tmp;- pwm_channel_writel(&led->pwmc, PWM_CDTY,- led->cdev.brightness * 255);- pwm_channel_writel(&led->pwmc, PWM_CPRD,- LED_FULL * tmp);-- pwm_channel_enable(&led->pwmc);-- /* Hand it over to the LED framework */- status = led_classdev_register(&pdev->dev, &led->cdev);- if (status < 0) {- pwm_channel_free(&led->pwmc);- goto err;- }- }-- platform_set_drvdata(pdev, leds);- return 0;--err:- if (i > 0) {- for (i = i - 1; i >= 0; i--) {- led_classdev_unregister(&leds[i].cdev);- pwm_channel_free(&leds[i].pwmc);- }- }-- return status;-}--static int pwmled_remove(struct platform_device *pdev)-{- const struct gpio_led_platform_data *pdata;- struct pwmled *leds;- unsigned i;-- pdata = dev_get_platdata(&pdev->dev);- leds = platform_get_drvdata(pdev);-- for (i = 0; i < pdata->num_leds; i++) {- struct pwmled *led = leds + i;-- led_classdev_unregister(&led->cdev);- pwm_channel_free(&led->pwmc);- }-- return 0;-}--static struct platform_driver pwmled_driver = {- .driver = {- .name = "leds-atmel-pwm",- .owner = THIS_MODULE,- },- /* REVISIT add suspend() and resume() methods */- .probe = pwmled_probe,- .remove = pwmled_remove,-};--module_platform_driver(pwmled_driver);--MODULE_DESCRIPTION("Driver for LEDs with PWM-controlled brightness");-MODULE_LICENSE("GPL");-MODULE_ALIAS("platform:leds-atmel-pwm");--
From: Nicolas Ferre <hidden> Date: 2014-03-27 17:43:36
On 19/03/2014 14:03, Alexandre Belloni :
Hi,
This patch set swtiches the at91 and avr32 SoCs and board to the generic PWM
framework. This allows to remove the obsolete leds-atmel-pwm, atmel-pwm-bl and
atmel_pwm drivers.
The first 6 patches take care of the AT91 boards and removes a useless function
in the process.
Patch 7 makes pwm-ateml buildable for AVR32
Patch 8 allows setting the pwm polarity for pwm_bl when using platform data.
This is required afterwards for the favr-32
Patches 9-13 take care of the AVR32 boards. This has only been compile tested as
I don't own any of those boards.
And the last 3 patches are removing the now obsolete drivers.
As a note, the atmel_pwm driver has two features not yet available through
pwm-atmel:
- it is possible to pass an IRQ handler that will get called each time one of
the channel period has been acheived.
- it was possible to set clka and clkb, two clock that divided mck before
feeding the pwm controller.
Those features are not used by anything in the mainline. I'm not sure we can
implement the first one. We'll get back the second one once all the boards have
swtiched to the common clock framework.
Alexandre Belloni (16):
ARM: at91: at91sam9g45: switch to generic PWM framework
ARM: at91: sam9m10g45ek: use generic leds_pwm driver
ARM: at91: at91sam9263: switch to generic PWM framework
ARM: at91: sam9263ek: use generic leds_pwm driver
ARM: at91: at91sam9rl: switch to generic PWM framework
ARM: at91: remove useless at91_pwm_leds()
PWM: atmel: allow building for AVR32
backlight: pwm_bl: set pwm polarity when using platform data
avr32/at32ap: switch to the generic PWM framework
avr32: MRMT: use generic leds_pwm driver
avr32: merisc: use generic leds_pwm driver
avr32: favr-32: use generic pwm_bl driver
avr32: update defconfig to use the generic PWM framework
backlight: atmel-pwm-bl: remove obsolete driver
leds: atmel-pwm: remove obsolete driver
misc: atmel_pwm: remove obsolete driver
I am fine with the whole series. For the AT91 specific bits, you can add my:
Acked-by: Nicolas Ferre <redacted>
It is a very nice cleanup and I can take the series with me in the AT91
git tree (likely the at91-3.16-cleanup or at91-3.16-drivers branch) if
everybody agree.
Bye,
Hi,
On 27/03/2014 at 18:43:26 +0100, Nicolas Ferre wrote :
On 19/03/2014 14:03, Alexandre Belloni :
quoted
Alexandre Belloni (16):
ARM: at91: at91sam9g45: switch to generic PWM framework
ARM: at91: sam9m10g45ek: use generic leds_pwm driver
ARM: at91: at91sam9263: switch to generic PWM framework
ARM: at91: sam9263ek: use generic leds_pwm driver
ARM: at91: at91sam9rl: switch to generic PWM framework
ARM: at91: remove useless at91_pwm_leds()
PWM: atmel: allow building for AVR32
backlight: pwm_bl: set pwm polarity when using platform data
Please wait for Thierry Reding to comment on this one...
quoted
avr32/at32ap: switch to the generic PWM framework
avr32: MRMT: use generic leds_pwm driver
avr32: merisc: use generic leds_pwm driver
avr32: favr-32: use generic pwm_bl driver
avr32: update defconfig to use the generic PWM framework
backlight: atmel-pwm-bl: remove obsolete driver
leds: atmel-pwm: remove obsolete driver
...watch out for the small typo (pawm-atmel) I made there...
quoted
misc: atmel_pwm: remove obsolete driver
I am fine with the whole series. For the AT91 specific bits, you can add my:
Acked-by: Nicolas Ferre <redacted>
It is a very nice cleanup and I can take the series with me in the AT91
git tree (likely the at91-3.16-cleanup or at91-3.16-drivers branch) if
everybody agree.
... but I believe you can take it through your tree as it mostly depends
on AT91 and Hans-Christian seemed fine with the modifications on avr32.
Regards,
--
Alexandre Belloni, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
On Wed, Mar 19, 2014 at 02:03:21PM +0100, Alexandre Belloni wrote:
quoted hunk
Set inversed polarity when .pwm_active_low is set in the platform_data. With
device tree, this is taken care of by of_pwm_xlate_with_flags(), called from
of_pwm_get().
Signed-off-by: Alexandre Belloni <redacted>
---
drivers/video/backlight/pwm_bl.c | 8 ++++++++
include/linux/pwm_backlight.h | 1 +
2 files changed, 9 insertions(+)
@@ -309,6 +309,14 @@ static int pwm_backlight_probe(struct platform_device *pdev)if(data->pwm_period_ns>0)pwm_set_period(pb->pwm,data->pwm_period_ns);+/*+*TheDTcaseistakingcareofpolarityinof_pwm_get().Forthe+*non-DTcase,setthepolarityfromplatformdata.+*/+if(data->pwm_active_low)+if(pwm_set_polarity(pb->pwm,PWM_POLARITY_INVERSED))+dev_err(&pdev->dev,"impossible to invert polarity\n");
Could this perhaps be solved by adding a field to the PWM lookup table
that's used for non-DT cases? The idea being that we can use the same
interfaces for DT and non-DT cases, so we should try to move both
towards the same representation.
Thierry
I found this a tiny bit weird, but found the matching instance in
drivers/pwm/pwm-atmel.c
IMHO it would initially have been better to call it atpwm_v1 or something
similar, more generic. But I guess that is too late to change at this point.
Generally when you call clk_get(dev, NULL), you'll pass in the consumer
device as "dev". Now the avr32 clock implementation compares that to the
device associated with the clock, which for the case of the PWM pwm0_mck
is the PWM controller (at32_add_device_pwm() for reference). So it seems
to be set up properly (the PWM controller is the consumer).
Also since the consumer ID isn't specified to the clk_get() call, the
name of the clock (what's being changed in the above hunk) shouldn't
matter because it won't match anyway.
Now that I look at it more closely, I wonder how clk_get(dev, NULL) can
even work on avr32, since there's no check for id == NULL and therefore
NULL will be blindly passed into strcmp() and then crash.
Thierry