* [PATCH 08/16] backlight: pwm_bl: set pwm polarity when using platform data
From: Alexandre Belloni @ 2014-03-19 13:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1395234209-15546-1-git-send-email-alexandre.belloni@free-electrons.com>
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 <alexandre.belloni@free-electrons.com>
---
drivers/video/backlight/pwm_bl.c | 8 ++++++++
include/linux/pwm_backlight.h | 1 +
2 files changed, 9 insertions(+)
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index b75201ff46f6..ffdd3b2b2742 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -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);
+ /*
+ * The DT case is taking care of polarity in of_pwm_get(). For the
+ * non-DT case, set the polarity from platform data.
+ */
+ if (data->pwm_active_low)
+ if (pwm_set_polarity(pb->pwm, PWM_POLARITY_INVERSED))
+ dev_err(&pdev->dev, "impossible to invert polarity\n");
+
pb->period = pwm_get_period(pb->pwm);
pb->lth_brightness = data->lth_brightness * (pb->period / pb->scale);
diff --git a/include/linux/pwm_backlight.h b/include/linux/pwm_backlight.h
index 2de2e275b2cb..b924fce5c97a 100644
--- a/include/linux/pwm_backlight.h
+++ b/include/linux/pwm_backlight.h
@@ -15,6 +15,7 @@ struct platform_pwm_backlight_data {
unsigned int dft_brightness;
unsigned int lth_brightness;
unsigned int pwm_period_ns;
+ bool pwm_active_low;
unsigned int *levels;
int enable_gpio;
unsigned long enable_gpio_flags;
--
1.8.3.2
^ permalink raw reply related
* [PATCH 09/16] avr32/at32ap: switch to the generic PWM framework
From: Alexandre Belloni @ 2014-03-19 13:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1395234209-15546-1-git-send-email-alexandre.belloni@free-electrons.com>
Switch to the pwm/pwm-atmel driver instead of misc/atmel_pwm
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
arch/avr32/mach-at32ap/at32ap700x.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c
index a1f4d1e91b52..db85b5ec3351 100644
--- a/arch/avr32/mach-at32ap/at32ap700x.c
+++ b/arch/avr32/mach-at32ap/at32ap700x.c
@@ -1553,7 +1553,7 @@ static struct resource atmel_pwm0_resource[] __initdata = {
IRQ(24),
};
static struct clk atmel_pwm0_mck = {
- .name = "pwm_clk",
+ .name = "at91sam9rl-pwm",
.parent = &pbb_clk,
.mode = pbb_clk_mode,
.get_rate = pbb_clk_get_rate,
@@ -1568,7 +1568,7 @@ struct platform_device *__init at32_add_device_pwm(u32 mask)
if (!mask)
return NULL;
- pdev = platform_device_alloc("atmel_pwm", 0);
+ pdev = platform_device_alloc("at91sam9rl-pwm", 0);
if (!pdev)
return NULL;
@@ -1576,9 +1576,6 @@ struct platform_device *__init at32_add_device_pwm(u32 mask)
ARRAY_SIZE(atmel_pwm0_resource)))
goto out_free_pdev;
- if (platform_device_add_data(pdev, &mask, sizeof(mask)))
- goto out_free_pdev;
-
pin_mask = 0;
if (mask & (1 << 0))
pin_mask |= (1 << 28);
--
1.8.3.2
^ permalink raw reply related
* [PATCH 10/16] avr32: MRMT: use generic leds_pwm driver
From: Alexandre Belloni @ 2014-03-19 13:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1395234209-15546-1-git-send-email-alexandre.belloni@free-electrons.com>
Switch to the generic leds_pwm driver instead of leds-atmel-pwm.
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
arch/avr32/boards/atngw100/mrmt.c | 35 +++++++++++++++++++++++------------
1 file changed, 23 insertions(+), 12 deletions(-)
diff --git a/arch/avr32/boards/atngw100/mrmt.c b/arch/avr32/boards/atngw100/mrmt.c
index 1ba09e4c02b1..134e94c3d504 100644
--- a/arch/avr32/boards/atngw100/mrmt.c
+++ b/arch/avr32/boards/atngw100/mrmt.c
@@ -17,6 +17,8 @@
#include <linux/types.h>
#include <linux/fb.h>
#include <linux/leds.h>
+#include <linux/pwm.h>
+#include <linux/leds_pwm.h>
#include <linux/input.h>
#include <linux/gpio_keys.h>
#include <linux/atmel_serial.h>
@@ -155,21 +157,29 @@ static struct platform_device rmt_ts_device = {
#ifdef CONFIG_BOARD_MRMT_BL_PWM
/* PWM LEDs: LCD Backlight, etc */
-static struct gpio_led rmt_pwm_led[] = {
- /* here the "gpio" is actually a PWM channel */
- { .name = "backlight", .gpio = PWM_CH_BL, },
+static struct pwm_lookup pwm_lookup[] = {
+ PWM_LOOKUP("at91sam9rl-pwm", PWM_CH_BL, "leds_pwm", "ds1"),
};
-static struct gpio_led_platform_data rmt_pwm_led_data = {
- .num_leds = ARRAY_SIZE(rmt_pwm_led),
- .leds = rmt_pwm_led,
+static struct led_pwm pwm_leds[] = {
+ {
+ .name = "backlight",
+ .max_brightness = 255,
+ .pwm_period_ns = 5000,
+ .active_low = 1,
+ },
+};
+
+static struct led_pwm_platform_data pwm_data = {
+ .num_leds = ARRAY_SIZE(pwm_leds),
+ .leds = pwm_leds,
};
-static struct platform_device rmt_pwm_led_dev = {
- .name = "leds-atmel-pwm",
- .id = -1,
- .dev = {
- .platform_data = &rmt_pwm_led_data,
+static struct platform_device leds_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 );
--
1.8.3.2
^ permalink raw reply related
* [PATCH 11/16] avr32: merisc: use generic leds_pwm driver
From: Alexandre Belloni @ 2014-03-19 13:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1395234209-15546-1-git-send-email-alexandre.belloni@free-electrons.com>
Switch to the generic leds_pwm driver instead of leds-atmel-pwm.
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
arch/avr32/boards/merisc/setup.c | 34 +++++++++++++++++++++-------------
1 file changed, 21 insertions(+), 13 deletions(-)
diff --git a/arch/avr32/boards/merisc/setup.c b/arch/avr32/boards/merisc/setup.c
index ed137e335796..b0980c1946a7 100644
--- a/arch/avr32/boards/merisc/setup.c
+++ b/arch/avr32/boards/merisc/setup.c
@@ -22,6 +22,8 @@
#include <linux/irq.h>
#include <linux/fb.h>
#include <linux/atmel-mci.h>
+#include <linux/pwm.h>
+#include <linux/leds_pwm.h>
#include <asm/io.h>
#include <asm/setup.h>
@@ -167,24 +169,29 @@ static struct i2c_board_info __initdata i2c_info[] = {
},
};
-#ifdef CONFIG_LEDS_ATMEL_PWM
-static struct gpio_led stk_pwm_led[] = {
+#if IS_ENABLED(CONFIG_LEDS_PWM)
+static struct pwm_lookup pwm_lookup[] = {
+ PWM_LOOKUP("at91sam9rl-pwm", 0, "leds_pwm", "backlight"),
+};
+
+static struct led_pwm pwm_leds[] = {
{
.name = "backlight",
- .gpio = 0, /* PWM channel 0 (LCD backlight) */
+ .max_brightness = 255,
+ .pwm_period_ns = 5000,
},
};
-static struct gpio_led_platform_data stk_pwm_led_data = {
- .num_leds = ARRAY_SIZE(stk_pwm_led),
- .leds = stk_pwm_led,
+static struct led_pwm_platform_data pwm_data = {
+ .num_leds = ARRAY_SIZE(pwm_leds),
+ .leds = pwm_leds,
};
-static struct platform_device stk_pwm_led_dev = {
- .name = "leds-atmel-pwm",
- .id = -1,
- .dev = {
- .platform_data = &stk_pwm_led_data,
+static struct platform_device leds_pwm = {
+ .name = "leds_pwm",
+ .id = -1,
+ .dev = {
+ .platform_data = &pwm_data,
},
};
#endif
@@ -278,9 +285,10 @@ static int __init merisc_init(void)
at32_add_device_mci(0, &mci0_data);
-#ifdef CONFIG_LEDS_ATMEL_PWM
+#if IS_ENABLED(CONFIG_LEDS_PWM)
+ pwm_add_table(pwm_lookup, ARRAY_SIZE(pwm_lookup));
at32_add_device_pwm((1 << 0) | (1 << 2));
- platform_device_register(&stk_pwm_led_dev);
+ platform_device_register(&leds_pwm);
#else
at32_add_device_pwm((1 << 2));
#endif
--
1.8.3.2
^ permalink raw reply related
* [PATCH 12/16] avr32: favr-32: use generic pwm_bl driver
From: Alexandre Belloni @ 2014-03-19 13:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1395234209-15546-1-git-send-email-alexandre.belloni@free-electrons.com>
Switch to the generic pwm_bl driver instead of atmel-pwm-bl.
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
arch/avr32/boards/favr-32/setup.c | 49 +++++++++++++++++++++++-------------
arch/avr32/configs/favr-32_defconfig | 6 ++---
2 files changed, 34 insertions(+), 21 deletions(-)
diff --git a/arch/avr32/boards/favr-32/setup.c b/arch/avr32/boards/favr-32/setup.c
index 1f121497b517..391f026705a5 100644
--- a/arch/avr32/boards/favr-32/setup.c
+++ b/arch/avr32/boards/favr-32/setup.c
@@ -18,7 +18,10 @@
#include <linux/gpio.h>
#include <linux/leds.h>
#include <linux/atmel-mci.h>
-#include <linux/atmel-pwm-bl.h>
+#include <linux/pwm.h>
+#include <linux/pwm_backlight.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
@@ -33,6 +36,8 @@
#include <mach/board.h>
#include <mach/portmux.h>
+#define PWM_BL_CH 2
+
/* Oscillator frequencies. These are board-specific */
unsigned long at32_board_osc_rates[3] = {
[0] = 32768, /* 32.768 kHz on RTC osc */
@@ -227,29 +232,37 @@ void __init favr32_setup_leds(void)
platform_device_register(&favr32_led_dev);
}
-static struct atmel_pwm_bl_platform_data atmel_pwm_bl_pdata = {
- .pwm_channel = 2,
- .pwm_frequency = 200000,
- .pwm_compare_max = 345,
- .pwm_duty_max = 345,
- .pwm_duty_min = 90,
- .pwm_active_low = 1,
- .gpio_on = GPIO_PIN_PA(28),
- .on_active_low = 0,
+static struct pwm_lookup pwm_lookup[] = {
+ PWM_LOOKUP("at91sam9rl-pwm", PWM_BL_CH, "pwm-backlight.0", NULL),
};
-static struct platform_device atmel_pwm_bl_dev = {
- .name = "atmel-pwm-bl",
- .id = 0,
- .dev = {
- .platform_data = &atmel_pwm_bl_pdata,
+static struct regulator_consumer_supply fixed_power_consumers[] = {
+ REGULATOR_SUPPLY("power", "pwm-backlight.0"),
+};
+
+static struct platform_pwm_backlight_data pwm_bl_data = {
+ .enable_gpio = GPIO_PIN_PA(28),
+ .pwm_period_ns = 5000,
+ .max_brightness = 255,
+ .dft_brightness = 255,
+ .lth_brightness = 50,
+ .pwm_active_low = true,
+};
+
+static struct platform_device pwm_bl_device = {
+ .name = "pwm-backlight",
+ .dev = {
+ .platform_data = &pwm_bl_data,
},
};
static void __init favr32_setup_atmel_pwm_bl(void)
{
- platform_device_register(&atmel_pwm_bl_dev);
- at32_select_gpio(atmel_pwm_bl_pdata.gpio_on, 0);
+ pwm_add_table(pwm_lookup, ARRAY_SIZE(pwm_lookup));
+ regulator_register_always_on(0, "fixed", fixed_power_consumers,
+ ARRAY_SIZE(fixed_power_consumers), 3300000);
+ platform_device_register(&pwm_bl_device);
+ at32_select_gpio(pwm_bl_data.enable_gpio, 0);
}
void __init setup_board(void)
@@ -339,7 +352,7 @@ static int __init favr32_init(void)
set_abdac_rate(at32_add_device_abdac(0, &abdac0_data));
- at32_add_device_pwm(1 << atmel_pwm_bl_pdata.pwm_channel);
+ at32_add_device_pwm(1 << PWM_BL_CH);
at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
at32_add_device_mci(0, &mci0_data);
at32_add_device_usba(0, NULL);
diff --git a/arch/avr32/configs/favr-32_defconfig b/arch/avr32/configs/favr-32_defconfig
index 07bed3f7eb5e..b3eb67dc05ac 100644
--- a/arch/avr32/configs/favr-32_defconfig
+++ b/arch/avr32/configs/favr-32_defconfig
@@ -67,7 +67,6 @@ CONFIG_MTD_PHYSMAP=y
CONFIG_BLK_DEV_LOOP=m
CONFIG_BLK_DEV_NBD=m
CONFIG_BLK_DEV_RAM=m
-CONFIG_ATMEL_PWM=m
CONFIG_ATMEL_TCLIB=y
CONFIG_ATMEL_SSC=m
CONFIG_NETDEVICES=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
@@ -123,7 +122,6 @@ CONFIG_MMC=y
CONFIG_MMC_ATMELMCI=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_ATMEL_PWM=m
CONFIG_LEDS_GPIO=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
@@ -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
--
1.8.3.2
^ permalink raw reply related
* [PATCH 13/16] avr32: update defconfig to use the generic PWM framework
From: Alexandre Belloni @ 2014-03-19 13:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1395234209-15546-1-git-send-email-alexandre.belloni@free-electrons.com>
Now that all boards have switch to the generic PWM framework, update the
defconfigs to use it.
Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
---
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/merisc_defconfig | 5 +++--
6 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/arch/avr32/configs/atngw100_mrmt_defconfig b/arch/avr32/configs/atngw100_mrmt_defconfig
index 9a57da44eb6f..6838781e966f 100644
--- a/arch/avr32/configs/atngw100_mrmt_defconfig
+++ b/arch/avr32/configs/atngw100_mrmt_defconfig
@@ -56,7 +56,6 @@ CONFIG_MTD_CFI_AMDSTD=y
CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_DATAFLASH=y
CONFIG_BLK_DEV_LOOP=y
-CONFIG_ATMEL_PWM=y
CONFIG_NETDEVICES=y
CONFIG_NET_ETHERNET=y
CONFIG_MACB=y
@@ -104,8 +103,8 @@ CONFIG_MMC=y
CONFIG_MMC_ATMELMCI=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_ATMEL_PWM=y
CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_PWM=y
CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y
CONFIG_LEDS_TRIGGER_HEARTBEAT=y
@@ -114,6 +113,8 @@ CONFIG_RTC_DRV_S35390A=m
CONFIG_RTC_DRV_AT32AP700X=m
CONFIG_DMADEVICES=y
CONFIG_UIO=y
+CONFIG_PWM=y
+CONFIG_PWM_ATMEL=y
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT3_FS=y
diff --git a/arch/avr32/configs/atstk1002_defconfig b/arch/avr32/configs/atstk1002_defconfig
index 2813dd2b9138..b056820eef33 100644
--- a/arch/avr32/configs/atstk1002_defconfig
+++ b/arch/avr32/configs/atstk1002_defconfig
@@ -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
diff --git a/arch/avr32/configs/atstk1003_defconfig b/arch/avr32/configs/atstk1003_defconfig
index f8ff3a3baad4..0cd23a303da1 100644
--- a/arch/avr32/configs/atstk1003_defconfig
+++ b/arch/avr32/configs/atstk1003_defconfig
@@ -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
diff --git a/arch/avr32/configs/atstk1004_defconfig b/arch/avr32/configs/atstk1004_defconfig
index 992228e54e38..ac1041f5f85a 100644
--- a/arch/avr32/configs/atstk1004_defconfig
+++ b/arch/avr32/configs/atstk1004_defconfig
@@ -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
diff --git a/arch/avr32/configs/atstk1006_defconfig b/arch/avr32/configs/atstk1006_defconfig
index b8e698b0d1fa..ea4f670cb995 100644
--- a/arch/avr32/configs/atstk1006_defconfig
+++ b/arch/avr32/configs/atstk1006_defconfig
@@ -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
diff --git a/arch/avr32/configs/merisc_defconfig b/arch/avr32/configs/merisc_defconfig
index 91df6b2986be..b9ef4cc85d08 100644
--- a/arch/avr32/configs/merisc_defconfig
+++ b/arch/avr32/configs/merisc_defconfig
@@ -55,7 +55,6 @@ CONFIG_MTD_ABSENT=y
CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_BLOCK2MTD=y
CONFIG_BLK_DEV_LOOP=y
-CONFIG_ATMEL_PWM=y
CONFIG_ATMEL_SSC=y
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
@@ -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
--
1.8.3.2
^ permalink raw reply related
* [PATCH 14/16] backlight: atmel-pwm-bl: remove obsolete driver
From: Alexandre Belloni @ 2014-03-19 13:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1395234209-15546-1-git-send-email-alexandre.belloni@free-electrons.com>
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 <alexandre.belloni@free-electrons.com>
---
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
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 5a3eb2ecb525..9bd32b7a7561 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -178,17 +178,6 @@ config BACKLIGHT_ATMEL_LCDC
If in doubt, it's safe to enable this option; it doesn't kick
in unless the board's description says it's wired that way.
-config BACKLIGHT_ATMEL_PWM
- tristate "Atmel PWM backlight control"
- depends on ATMEL_PWM
- help
- Say Y here if you want to use the PWM peripheral in Atmel AT91 and
- AVR32 devices. This driver will need additional platform data to know
- which PWM instance to use and how to configure it.
-
- To compile this driver as a module, choose M here: the module will be
- called atmel-pwm-bl.
-
config BACKLIGHT_EP93XX
tristate "Cirrus EP93xx Backlight Driver"
depends on FB_EP93XX
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index bb820024f346..351451dbb607 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -25,7 +25,6 @@ obj-$(CONFIG_BACKLIGHT_ADP8860) += adp8860_bl.o
obj-$(CONFIG_BACKLIGHT_ADP8870) += adp8870_bl.o
obj-$(CONFIG_BACKLIGHT_APPLE) += apple_bl.o
obj-$(CONFIG_BACKLIGHT_AS3711) += as3711_bl.o
-obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o
obj-$(CONFIG_BACKLIGHT_BD6107) += bd6107.o
obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
diff --git a/drivers/video/backlight/atmel-pwm-bl.c b/drivers/video/backlight/atmel-pwm-bl.c
deleted file mode 100644
index 261b1a4ec3d8..000000000000
--- a/drivers/video/backlight/atmel-pwm-bl.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (C) 2008 Atmel Corporation
- *
- * Backlight driver using Atmel PWM peripheral.
- *
- * 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.
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/fb.h>
-#include <linux/gpio.h>
-#include <linux/backlight.h>
-#include <linux/atmel_pwm.h>
-#include <linux/atmel-pwm-bl.h>
-#include <linux/slab.h>
-
-struct atmel_pwm_bl {
- const struct atmel_pwm_bl_platform_data *pdata;
- struct backlight_device *bldev;
- struct platform_device *pdev;
- struct pwm_channel pwmc;
- int gpio_on;
-};
-
-static void atmel_pwm_bl_set_gpio_on(struct atmel_pwm_bl *pwmbl, int on)
-{
- if (!gpio_is_valid(pwmbl->gpio_on))
- return;
-
- gpio_set_value(pwmbl->gpio_on, on ^ pwmbl->pdata->on_active_low);
-}
-
-static int atmel_pwm_bl_set_intensity(struct backlight_device *bd)
-{
- struct atmel_pwm_bl *pwmbl = bl_get_data(bd);
- int intensity = bd->props.brightness;
- int pwm_duty;
-
- if (bd->props.power != FB_BLANK_UNBLANK)
- intensity = 0;
- if (bd->props.fb_blank != FB_BLANK_UNBLANK)
- intensity = 0;
-
- if (pwmbl->pdata->pwm_active_low)
- pwm_duty = pwmbl->pdata->pwm_duty_min + intensity;
- else
- pwm_duty = pwmbl->pdata->pwm_duty_max - intensity;
-
- if (pwm_duty > pwmbl->pdata->pwm_duty_max)
- pwm_duty = pwmbl->pdata->pwm_duty_max;
- if (pwm_duty < pwmbl->pdata->pwm_duty_min)
- pwm_duty = pwmbl->pdata->pwm_duty_min;
-
- if (!intensity) {
- atmel_pwm_bl_set_gpio_on(pwmbl, 0);
- pwm_channel_writel(&pwmbl->pwmc, PWM_CUPD, pwm_duty);
- pwm_channel_disable(&pwmbl->pwmc);
- } else {
- pwm_channel_enable(&pwmbl->pwmc);
- pwm_channel_writel(&pwmbl->pwmc, PWM_CUPD, pwm_duty);
- atmel_pwm_bl_set_gpio_on(pwmbl, 1);
- }
-
- return 0;
-}
-
-static int atmel_pwm_bl_get_intensity(struct backlight_device *bd)
-{
- struct atmel_pwm_bl *pwmbl = bl_get_data(bd);
- u32 cdty;
- u32 intensity;
-
- cdty = pwm_channel_readl(&pwmbl->pwmc, PWM_CDTY);
- if (pwmbl->pdata->pwm_active_low)
- intensity = cdty - pwmbl->pdata->pwm_duty_min;
- else
- intensity = pwmbl->pdata->pwm_duty_max - cdty;
-
- return intensity & 0xffff;
-}
-
-static int atmel_pwm_bl_init_pwm(struct atmel_pwm_bl *pwmbl)
-{
- unsigned long pwm_rate = pwmbl->pwmc.mck;
- unsigned long prescale = DIV_ROUND_UP(pwm_rate,
- (pwmbl->pdata->pwm_frequency *
- pwmbl->pdata->pwm_compare_max)) - 1;
-
- /*
- * Prescale must be power of two and maximum 0xf in size because of
- * hardware limit. PWM speed will be:
- * PWM module clock speed / (2 ^ prescale).
- */
- prescale = fls(prescale);
- if (prescale > 0xf)
- prescale = 0xf;
-
- pwm_channel_writel(&pwmbl->pwmc, PWM_CMR, prescale);
- pwm_channel_writel(&pwmbl->pwmc, PWM_CDTY,
- pwmbl->pdata->pwm_duty_min +
- pwmbl->bldev->props.brightness);
- pwm_channel_writel(&pwmbl->pwmc, PWM_CPRD,
- pwmbl->pdata->pwm_compare_max);
-
- dev_info(&pwmbl->pdev->dev, "Atmel PWM backlight driver (%lu Hz)\n",
- pwmbl->pwmc.mck / pwmbl->pdata->pwm_compare_max /
- (1 << prescale));
-
- return pwm_channel_enable(&pwmbl->pwmc);
-}
-
-static const struct backlight_ops atmel_pwm_bl_ops = {
- .get_brightness = atmel_pwm_bl_get_intensity,
- .update_status = atmel_pwm_bl_set_intensity,
-};
-
-static int atmel_pwm_bl_probe(struct platform_device *pdev)
-{
- struct backlight_properties props;
- const struct atmel_pwm_bl_platform_data *pdata;
- struct backlight_device *bldev;
- struct atmel_pwm_bl *pwmbl;
- unsigned long flags;
- int retval;
-
- pdata = dev_get_platdata(&pdev->dev);
- if (!pdata)
- return -ENODEV;
-
- if (pdata->pwm_compare_max < pdata->pwm_duty_max ||
- pdata->pwm_duty_min > pdata->pwm_duty_max ||
- pdata->pwm_frequency = 0)
- return -EINVAL;
-
- pwmbl = devm_kzalloc(&pdev->dev, sizeof(struct atmel_pwm_bl),
- GFP_KERNEL);
- if (!pwmbl)
- return -ENOMEM;
-
- pwmbl->pdev = pdev;
- pwmbl->pdata = pdata;
- pwmbl->gpio_on = pdata->gpio_on;
-
- retval = pwm_channel_alloc(pdata->pwm_channel, &pwmbl->pwmc);
- if (retval)
- return retval;
-
- if (gpio_is_valid(pwmbl->gpio_on)) {
- /* Turn display off by default. */
- if (pdata->on_active_low)
- flags = GPIOF_OUT_INIT_HIGH;
- else
- flags = GPIOF_OUT_INIT_LOW;
-
- retval = devm_gpio_request_one(&pdev->dev, pwmbl->gpio_on,
- flags, "gpio_atmel_pwm_bl");
- if (retval)
- goto err_free_pwm;
- }
-
- memset(&props, 0, sizeof(struct backlight_properties));
- props.type = BACKLIGHT_RAW;
- props.max_brightness = pdata->pwm_duty_max - pdata->pwm_duty_min;
- bldev = devm_backlight_device_register(&pdev->dev, "atmel-pwm-bl",
- &pdev->dev, pwmbl, &atmel_pwm_bl_ops,
- &props);
- if (IS_ERR(bldev)) {
- retval = PTR_ERR(bldev);
- goto err_free_pwm;
- }
-
- pwmbl->bldev = bldev;
-
- platform_set_drvdata(pdev, pwmbl);
-
- /* Power up the backlight by default at middle intesity. */
- bldev->props.power = FB_BLANK_UNBLANK;
- bldev->props.brightness = bldev->props.max_brightness / 2;
-
- retval = atmel_pwm_bl_init_pwm(pwmbl);
- if (retval)
- goto err_free_pwm;
-
- atmel_pwm_bl_set_intensity(bldev);
-
- return 0;
-
-err_free_pwm:
- pwm_channel_free(&pwmbl->pwmc);
-
- return retval;
-}
-
-static int atmel_pwm_bl_remove(struct platform_device *pdev)
-{
- struct atmel_pwm_bl *pwmbl = platform_get_drvdata(pdev);
-
- atmel_pwm_bl_set_gpio_on(pwmbl, 0);
- pwm_channel_disable(&pwmbl->pwmc);
- pwm_channel_free(&pwmbl->pwmc);
-
- return 0;
-}
-
-static struct platform_driver atmel_pwm_bl_driver = {
- .driver = {
- .name = "atmel-pwm-bl",
- },
- /* REVISIT add suspend() and resume() */
- .probe = atmel_pwm_bl_probe,
- .remove = atmel_pwm_bl_remove,
-};
-
-module_platform_driver(atmel_pwm_bl_driver);
-
-MODULE_AUTHOR("Hans-Christian egtvedt <hans-christian.egtvedt@atmel.com>");
-MODULE_DESCRIPTION("Atmel PWM backlight driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:atmel-pwm-bl");
diff --git a/include/linux/atmel-pwm-bl.h b/include/linux/atmel-pwm-bl.h
deleted file mode 100644
index 0153a47806c2..000000000000
--- a/include/linux/atmel-pwm-bl.h
+++ /dev/null
@@ -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 */
--
1.8.3.2
^ permalink raw reply related
* [PATCH 15/16] leds: atmel-pwm: remove obsolete driver
From: Alexandre Belloni @ 2014-03-19 13:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1395234209-15546-1-git-send-email-alexandre.belloni@free-electrons.com>
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 <alexandre.belloni@free-electrons.com>
---
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
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 72156c123033..e7aca5f1e396 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -32,14 +32,6 @@ config LEDS_88PM860X
This option enables support for on-chip LED drivers found on Marvell
Semiconductor 88PM8606 PMIC.
-config LEDS_ATMEL_PWM
- tristate "LED Support using Atmel PWM outputs"
- depends on LEDS_CLASS
- depends on ATMEL_PWM
- help
- This option enables support for LEDs driven using outputs
- of the dedicated PWM controller found on newer Atmel SOCs.
-
config LEDS_LM3530
tristate "LCD Backlight driver for LM3530"
depends on LEDS_CLASS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 3cd76dbd9be2..6ee06559db45 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -6,7 +6,6 @@ obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o
# LED Platform Drivers
obj-$(CONFIG_LEDS_88PM860X) += leds-88pm860x.o
-obj-$(CONFIG_LEDS_ATMEL_PWM) += leds-atmel-pwm.o
obj-$(CONFIG_LEDS_BD2802) += leds-bd2802.o
obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o
obj-$(CONFIG_LEDS_LM3530) += leds-lm3530.o
diff --git a/drivers/leds/leds-atmel-pwm.c b/drivers/leds/leds-atmel-pwm.c
deleted file mode 100644
index 56cec8d6a2ac..000000000000
--- a/drivers/leds/leds-atmel-pwm.c
+++ /dev/null
@@ -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");
--
1.8.3.2
^ permalink raw reply related
* [PATCH 16/16] misc: atmel_pwm: remove obsolete driver
From: Alexandre Belloni @ 2014-03-19 13:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1395234209-15546-1-git-send-email-alexandre.belloni@free-electrons.com>
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 <alexandre.belloni@free-electrons.com>
---
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
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 6cb388e8fb7d..64ab12b8de9e 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -51,15 +51,6 @@ config AD525X_DPOT_SPI
To compile this driver as a module, choose M here: the
module will be called ad525x_dpot-spi.
-config ATMEL_PWM
- tristate "Atmel AT32/AT91 PWM support"
- depends on HAVE_CLK
- help
- This option enables device driver support for the PWM channels
- on certain Atmel processors. Pulse Width Modulation is used for
- purposes including software controlled power-efficient backlights
- on LCD displays, motor control, and waveform generation.
-
config ATMEL_TCLIB
bool "Atmel AT32/AT91 Timer/Counter Library"
depends on (AVR32 || ARCH_AT91)
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 99b9424ce31d..8dd44f924cb0 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -7,7 +7,6 @@ obj-$(CONFIG_AD525X_DPOT) += ad525x_dpot.o
obj-$(CONFIG_AD525X_DPOT_I2C) += ad525x_dpot-i2c.o
obj-$(CONFIG_AD525X_DPOT_SPI) += ad525x_dpot-spi.o
obj-$(CONFIG_INTEL_MID_PTI) += pti.o
-obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o
obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o
obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o
obj-$(CONFIG_BMP085) += bmp085.o
diff --git a/drivers/misc/atmel_pwm.c b/drivers/misc/atmel_pwm.c
deleted file mode 100644
index a6dc56e1bc58..000000000000
--- a/drivers/misc/atmel_pwm.c
+++ /dev/null
@@ -1,402 +0,0 @@
-#include <linux/module.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <linux/interrupt.h>
-#include <linux/platform_device.h>
-#include <linux/atmel_pwm.h>
-
-
-/*
- * This is a simple driver for the PWM controller found in various newer
- * Atmel SOCs, including the AVR32 series and the AT91sam9263.
- *
- * Chips with current Linux ports have only 4 PWM channels, out of max 32.
- * AT32UC3A and AT32UC3B chips have 7 channels (but currently no Linux).
- * Docs are inconsistent about the width of the channel counter registers;
- * it's at least 16 bits, but several places say 20 bits.
- */
-#define PWM_NCHAN 4 /* max 32 */
-
-struct pwm {
- spinlock_t lock;
- struct platform_device *pdev;
- u32 mask;
- int irq;
- void __iomem *base;
- struct clk *clk;
- struct pwm_channel *channel[PWM_NCHAN];
- void (*handler[PWM_NCHAN])(struct pwm_channel *);
-};
-
-
-/* global PWM controller registers */
-#define PWM_MR 0x00
-#define PWM_ENA 0x04
-#define PWM_DIS 0x08
-#define PWM_SR 0x0c
-#define PWM_IER 0x10
-#define PWM_IDR 0x14
-#define PWM_IMR 0x18
-#define PWM_ISR 0x1c
-
-static inline void pwm_writel(const struct pwm *p, unsigned offset, u32 val)
-{
- __raw_writel(val, p->base + offset);
-}
-
-static inline u32 pwm_readl(const struct pwm *p, unsigned offset)
-{
- return __raw_readl(p->base + offset);
-}
-
-static inline void __iomem *pwmc_regs(const struct pwm *p, int index)
-{
- return p->base + 0x200 + index * 0x20;
-}
-
-static struct pwm *pwm;
-
-static void pwm_dumpregs(struct pwm_channel *ch, char *tag)
-{
- struct device *dev = &pwm->pdev->dev;
-
- dev_dbg(dev, "%s: mr %08x, sr %08x, imr %08x\n",
- tag,
- pwm_readl(pwm, PWM_MR),
- pwm_readl(pwm, PWM_SR),
- pwm_readl(pwm, PWM_IMR));
- dev_dbg(dev,
- "pwm ch%d - mr %08x, dty %u, prd %u, cnt %u\n",
- ch->index,
- pwm_channel_readl(ch, PWM_CMR),
- pwm_channel_readl(ch, PWM_CDTY),
- pwm_channel_readl(ch, PWM_CPRD),
- pwm_channel_readl(ch, PWM_CCNT));
-}
-
-
-/**
- * pwm_channel_alloc - allocate an unused PWM channel
- * @index: identifies the channel
- * @ch: structure to be initialized
- *
- * Drivers allocate PWM channels according to the board's wiring, and
- * matching board-specific setup code. Returns zero or negative errno.
- */
-int pwm_channel_alloc(int index, struct pwm_channel *ch)
-{
- unsigned long flags;
- int status = 0;
-
- if (!pwm)
- return -EPROBE_DEFER;
-
- if (!(pwm->mask & 1 << index))
- return -ENODEV;
-
- if (index < 0 || index >= PWM_NCHAN || !ch)
- return -EINVAL;
- memset(ch, 0, sizeof *ch);
-
- spin_lock_irqsave(&pwm->lock, flags);
- if (pwm->channel[index])
- status = -EBUSY;
- else {
- clk_enable(pwm->clk);
-
- ch->regs = pwmc_regs(pwm, index);
- ch->index = index;
-
- /* REVISIT: ap7000 seems to go 2x as fast as we expect!! */
- ch->mck = clk_get_rate(pwm->clk);
-
- pwm->channel[index] = ch;
- pwm->handler[index] = NULL;
-
- /* channel and irq are always disabled when we return */
- pwm_writel(pwm, PWM_DIS, 1 << index);
- pwm_writel(pwm, PWM_IDR, 1 << index);
- }
- spin_unlock_irqrestore(&pwm->lock, flags);
- return status;
-}
-EXPORT_SYMBOL(pwm_channel_alloc);
-
-static int pwmcheck(struct pwm_channel *ch)
-{
- int index;
-
- if (!pwm)
- return -ENODEV;
- if (!ch)
- return -EINVAL;
- index = ch->index;
- if (index < 0 || index >= PWM_NCHAN || pwm->channel[index] != ch)
- return -EINVAL;
-
- return index;
-}
-
-/**
- * pwm_channel_free - release a previously allocated channel
- * @ch: the channel being released
- *
- * The channel is completely shut down (counter and IRQ disabled),
- * and made available for re-use. Returns zero, or negative errno.
- */
-int pwm_channel_free(struct pwm_channel *ch)
-{
- unsigned long flags;
- int t;
-
- spin_lock_irqsave(&pwm->lock, flags);
- t = pwmcheck(ch);
- if (t >= 0) {
- pwm->channel[t] = NULL;
- pwm->handler[t] = NULL;
-
- /* channel and irq are always disabled when we return */
- pwm_writel(pwm, PWM_DIS, 1 << t);
- pwm_writel(pwm, PWM_IDR, 1 << t);
-
- clk_disable(pwm->clk);
- t = 0;
- }
- spin_unlock_irqrestore(&pwm->lock, flags);
- return t;
-}
-EXPORT_SYMBOL(pwm_channel_free);
-
-int __pwm_channel_onoff(struct pwm_channel *ch, int enabled)
-{
- unsigned long flags;
- int t;
-
- /* OMITTED FUNCTIONALITY: starting several channels in synch */
-
- spin_lock_irqsave(&pwm->lock, flags);
- t = pwmcheck(ch);
- if (t >= 0) {
- pwm_writel(pwm, enabled ? PWM_ENA : PWM_DIS, 1 << t);
- t = 0;
- pwm_dumpregs(ch, enabled ? "enable" : "disable");
- }
- spin_unlock_irqrestore(&pwm->lock, flags);
-
- return t;
-}
-EXPORT_SYMBOL(__pwm_channel_onoff);
-
-/**
- * pwm_clk_alloc - allocate and configure CLKA or CLKB
- * @prescale: from 0..10, the power of two used to divide MCK
- * @div: from 1..255, the linear divisor to use
- *
- * Returns PWM_CPR_CLKA, PWM_CPR_CLKB, or negative errno. The allocated
- * clock will run with a period of (2^prescale * div) / MCK, or twice as
- * long if center aligned PWM output is used. The clock must later be
- * deconfigured using pwm_clk_free().
- */
-int pwm_clk_alloc(unsigned prescale, unsigned div)
-{
- unsigned long flags;
- u32 mr;
- u32 val = (prescale << 8) | div;
- int ret = -EBUSY;
-
- if (prescale >= 10 || div = 0 || div > 255)
- return -EINVAL;
-
- spin_lock_irqsave(&pwm->lock, flags);
- mr = pwm_readl(pwm, PWM_MR);
- if ((mr & 0xffff) = 0) {
- mr |= val;
- ret = PWM_CPR_CLKA;
- } else if ((mr & (0xffff << 16)) = 0) {
- mr |= val << 16;
- ret = PWM_CPR_CLKB;
- }
- if (ret > 0)
- pwm_writel(pwm, PWM_MR, mr);
- spin_unlock_irqrestore(&pwm->lock, flags);
- return ret;
-}
-EXPORT_SYMBOL(pwm_clk_alloc);
-
-/**
- * pwm_clk_free - deconfigure and release CLKA or CLKB
- *
- * Reverses the effect of pwm_clk_alloc().
- */
-void pwm_clk_free(unsigned clk)
-{
- unsigned long flags;
- u32 mr;
-
- spin_lock_irqsave(&pwm->lock, flags);
- mr = pwm_readl(pwm, PWM_MR);
- if (clk = PWM_CPR_CLKA)
- pwm_writel(pwm, PWM_MR, mr & ~(0xffff << 0));
- if (clk = PWM_CPR_CLKB)
- pwm_writel(pwm, PWM_MR, mr & ~(0xffff << 16));
- spin_unlock_irqrestore(&pwm->lock, flags);
-}
-EXPORT_SYMBOL(pwm_clk_free);
-
-/**
- * pwm_channel_handler - manage channel's IRQ handler
- * @ch: the channel
- * @handler: the handler to use, possibly NULL
- *
- * If the handler is non-null, the handler will be called after every
- * period of this PWM channel. If the handler is null, this channel
- * won't generate an IRQ.
- */
-int pwm_channel_handler(struct pwm_channel *ch,
- void (*handler)(struct pwm_channel *ch))
-{
- unsigned long flags;
- int t;
-
- spin_lock_irqsave(&pwm->lock, flags);
- t = pwmcheck(ch);
- if (t >= 0) {
- pwm->handler[t] = handler;
- pwm_writel(pwm, handler ? PWM_IER : PWM_IDR, 1 << t);
- t = 0;
- }
- spin_unlock_irqrestore(&pwm->lock, flags);
-
- return t;
-}
-EXPORT_SYMBOL(pwm_channel_handler);
-
-static irqreturn_t pwm_irq(int id, void *_pwm)
-{
- struct pwm *p = _pwm;
- irqreturn_t handled = IRQ_NONE;
- u32 irqstat;
- int index;
-
- spin_lock(&p->lock);
-
- /* ack irqs, then handle them */
- irqstat = pwm_readl(pwm, PWM_ISR);
-
- while (irqstat) {
- struct pwm_channel *ch;
- void (*handler)(struct pwm_channel *ch);
-
- index = ffs(irqstat) - 1;
- irqstat &= ~(1 << index);
- ch = pwm->channel[index];
- handler = pwm->handler[index];
- if (handler && ch) {
- spin_unlock(&p->lock);
- handler(ch);
- spin_lock(&p->lock);
- handled = IRQ_HANDLED;
- }
- }
-
- spin_unlock(&p->lock);
- return handled;
-}
-
-static int __init pwm_probe(struct platform_device *pdev)
-{
- struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- int irq = platform_get_irq(pdev, 0);
- u32 *mp = pdev->dev.platform_data;
- struct pwm *p;
- int status = -EIO;
-
- if (pwm)
- return -EBUSY;
- if (!r || irq < 0 || !mp || !*mp)
- return -ENODEV;
- if (*mp & ~((1<<PWM_NCHAN)-1)) {
- dev_warn(&pdev->dev, "mask 0x%x ... more than %d channels\n",
- *mp, PWM_NCHAN);
- return -EINVAL;
- }
-
- p = kzalloc(sizeof(*p), GFP_KERNEL);
- if (!p)
- return -ENOMEM;
-
- spin_lock_init(&p->lock);
- p->pdev = pdev;
- p->mask = *mp;
- p->irq = irq;
- p->base = ioremap(r->start, resource_size(r));
- if (!p->base)
- goto fail;
- p->clk = clk_get(&pdev->dev, "pwm_clk");
- if (IS_ERR(p->clk)) {
- status = PTR_ERR(p->clk);
- p->clk = NULL;
- goto fail;
- }
-
- status = request_irq(irq, pwm_irq, 0, pdev->name, p);
- if (status < 0)
- goto fail;
-
- pwm = p;
- platform_set_drvdata(pdev, p);
-
- return 0;
-
-fail:
- if (p->clk)
- clk_put(p->clk);
- if (p->base)
- iounmap(p->base);
-
- kfree(p);
- return status;
-}
-
-static int __exit pwm_remove(struct platform_device *pdev)
-{
- struct pwm *p = platform_get_drvdata(pdev);
-
- if (p != pwm)
- return -EINVAL;
-
- clk_enable(pwm->clk);
- pwm_writel(pwm, PWM_DIS, (1 << PWM_NCHAN) - 1);
- pwm_writel(pwm, PWM_IDR, (1 << PWM_NCHAN) - 1);
- clk_disable(pwm->clk);
-
- pwm = NULL;
-
- free_irq(p->irq, p);
- clk_put(p->clk);
- iounmap(p->base);
- kfree(p);
-
- return 0;
-}
-
-static struct platform_driver atmel_pwm_driver = {
- .driver = {
- .name = "atmel_pwm",
- .owner = THIS_MODULE,
- },
- .remove = __exit_p(pwm_remove),
-
- /* NOTE: PWM can keep running in AVR32 "idle" and "frozen" states;
- * and all AT91sam9263 states, albeit at reduced clock rate if
- * MCK becomes the slow clock (i.e. what Linux labels STR).
- */
-};
-
-module_platform_driver_probe(atmel_pwm_driver, pwm_probe);
-
-MODULE_DESCRIPTION("Driver for AT32/AT91 PWM module");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:atmel_pwm");
diff --git a/include/linux/atmel_pwm.h b/include/linux/atmel_pwm.h
deleted file mode 100644
index ea04abb3db8e..000000000000
--- a/include/linux/atmel_pwm.h
+++ /dev/null
@@ -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 */
--
1.8.3.2
^ permalink raw reply related
* Re: [PATCH v2] lcd: Provide dummy functions if CONFIG_LCD_CLASS_DEVICE is not set
From: Tomi Valkeinen @ 2014-03-19 13:31 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1394795353-1931-1-git-send-email-shc_work@mail.ru>
[-- Attachment #1: Type: text/plain, Size: 681 bytes --]
Hi,
On 14/03/14 13:09, Alexander Shiyan wrote:
> Provide dummy functions for LCD register()/unregister() if
> CONFIG_LCD_CLASS_DEVICE is not set.
> This allows us to use the LCD class as an optional.
>
> Signed-off-by: Alexander Shiyan <shc_work@mail.ru>
> ---
> include/linux/lcd.h | 37 ++++++++++++++++++++++++++++++-------
> 1 file changed, 30 insertions(+), 7 deletions(-)
I'm still not convinced about this. Isn't it simpler to just
select/depend on LCD_CLASS_DEVICE? The lcd.c is a bit less than 9 kB, so
it's not like you're adding a huge amount of code into the kernel even
if the driver doesn't happen to use it for a particular display.
Tomi
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 901 bytes --]
^ permalink raw reply
* Re: [PATCH 09/16] avr32/at32ap: switch to the generic PWM framework
From: Hans-Christian Egtvedt @ 2014-03-19 14:18 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1395234209-15546-10-git-send-email-alexandre.belloni@free-electrons.com>
Around Wed 19 Mar 2014 14:03:22 +0100 or thereabout, Alexandre Belloni wrote:
> Switch to the pwm/pwm-atmel driver instead of misc/atmel_pwm
>
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Acked-by: Hans-Christian Egtvedt <egtvedt@samfundet.no>
> ---
> arch/avr32/mach-at32ap/at32ap700x.c | 7 ++-----
> 1 file changed, 2 insertions(+), 5 deletions(-)
>
> diff --git a/arch/avr32/mach-at32ap/at32ap700x.c b/arch/avr32/mach-at32ap/at32ap700x.c
> index a1f4d1e91b52..db85b5ec3351 100644
> --- a/arch/avr32/mach-at32ap/at32ap700x.c
> +++ b/arch/avr32/mach-at32ap/at32ap700x.c
> @@ -1553,7 +1553,7 @@ static struct resource atmel_pwm0_resource[] __initdata = {
> IRQ(24),
> };
> static struct clk atmel_pwm0_mck = {
> - .name = "pwm_clk",
> + .name = "at91sam9rl-pwm",
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.
> .parent = &pbb_clk,
> .mode = pbb_clk_mode,
> .get_rate = pbb_clk_get_rate,
> @@ -1568,7 +1568,7 @@ struct platform_device *__init at32_add_device_pwm(u32 mask)
> if (!mask)
> return NULL;
>
> - pdev = platform_device_alloc("atmel_pwm", 0);
> + pdev = platform_device_alloc("at91sam9rl-pwm", 0);
> if (!pdev)
> return NULL;
>
> @@ -1576,9 +1576,6 @@ struct platform_device *__init at32_add_device_pwm(u32 mask)
> ARRAY_SIZE(atmel_pwm0_resource)))
> goto out_free_pdev;
>
> - if (platform_device_add_data(pdev, &mask, sizeof(mask)))
> - goto out_free_pdev;
> -
> pin_mask = 0;
> if (mask & (1 << 0))
> pin_mask |= (1 << 28);
--
mvh
Hans-Christian Egtvedt
^ permalink raw reply
* Re: [PATCH 10/16] avr32: MRMT: use generic leds_pwm driver
From: Hans-Christian Egtvedt @ 2014-03-19 14:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1395234209-15546-11-git-send-email-alexandre.belloni@free-electrons.com>
Around Wed 19 Mar 2014 14:03:23 +0100 or thereabout, Alexandre Belloni wrote:
> Switch to the generic leds_pwm driver instead of leds-atmel-pwm.
>
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Acked-by: Hans-Christian Egtvedt <egtvedt@samfundet.no>
I do not have this add-on board either, so I can only provide compile tests
myself.
> ---
> arch/avr32/boards/atngw100/mrmt.c | 35 +++++++++++++++++++++++------------
> 1 file changed, 23 insertions(+), 12 deletions(-)
>
> diff --git a/arch/avr32/boards/atngw100/mrmt.c b/arch/avr32/boards/atngw100/mrmt.c
> index 1ba09e4c02b1..134e94c3d504 100644
> --- a/arch/avr32/boards/atngw100/mrmt.c
> +++ b/arch/avr32/boards/atngw100/mrmt.c
> @@ -17,6 +17,8 @@
> #include <linux/types.h>
> #include <linux/fb.h>
> #include <linux/leds.h>
> +#include <linux/pwm.h>
> +#include <linux/leds_pwm.h>
> #include <linux/input.h>
> #include <linux/gpio_keys.h>
> #include <linux/atmel_serial.h>
> @@ -155,21 +157,29 @@ static struct platform_device rmt_ts_device = {
>
> #ifdef CONFIG_BOARD_MRMT_BL_PWM
> /* PWM LEDs: LCD Backlight, etc */
> -static struct gpio_led rmt_pwm_led[] = {
> - /* here the "gpio" is actually a PWM channel */
> - { .name = "backlight", .gpio = PWM_CH_BL, },
> +static struct pwm_lookup pwm_lookup[] = {
> + PWM_LOOKUP("at91sam9rl-pwm", PWM_CH_BL, "leds_pwm", "ds1"),
> };
>
> -static struct gpio_led_platform_data rmt_pwm_led_data = {
> - .num_leds = ARRAY_SIZE(rmt_pwm_led),
> - .leds = rmt_pwm_led,
> +static struct led_pwm pwm_leds[] = {
> + {
> + .name = "backlight",
> + .max_brightness = 255,
> + .pwm_period_ns = 5000,
> + .active_low = 1,
> + },
> +};
> +
> +static struct led_pwm_platform_data pwm_data = {
> + .num_leds = ARRAY_SIZE(pwm_leds),
> + .leds = pwm_leds,
> };
>
> -static struct platform_device rmt_pwm_led_dev = {
> - .name = "leds-atmel-pwm",
> - .id = -1,
> - .dev = {
> - .platform_data = &rmt_pwm_led_data,
> +static struct platform_device leds_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 );
--
mvh
Hans-Christian Egtvedt
^ permalink raw reply
* Re: [PATCH 11/16] avr32: merisc: use generic leds_pwm driver
From: Hans-Christian Egtvedt @ 2014-03-19 14:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1395234209-15546-12-git-send-email-alexandre.belloni@free-electrons.com>
Around Wed 19 Mar 2014 14:03:24 +0100 or thereabout, Alexandre Belloni wrote:
> Switch to the generic leds_pwm driver instead of leds-atmel-pwm.
>
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Acked-by: Hans-Christian Egtvedt <egtvedt@samfundet.no>
I do not have this board either.
> ---
> arch/avr32/boards/merisc/setup.c | 34 +++++++++++++++++++++-------------
> 1 file changed, 21 insertions(+), 13 deletions(-)
>
> diff --git a/arch/avr32/boards/merisc/setup.c b/arch/avr32/boards/merisc/setup.c
> index ed137e335796..b0980c1946a7 100644
> --- a/arch/avr32/boards/merisc/setup.c
> +++ b/arch/avr32/boards/merisc/setup.c
> @@ -22,6 +22,8 @@
> #include <linux/irq.h>
> #include <linux/fb.h>
> #include <linux/atmel-mci.h>
> +#include <linux/pwm.h>
> +#include <linux/leds_pwm.h>
>
> #include <asm/io.h>
> #include <asm/setup.h>
> @@ -167,24 +169,29 @@ static struct i2c_board_info __initdata i2c_info[] = {
> },
> };
>
> -#ifdef CONFIG_LEDS_ATMEL_PWM
> -static struct gpio_led stk_pwm_led[] = {
> +#if IS_ENABLED(CONFIG_LEDS_PWM)
> +static struct pwm_lookup pwm_lookup[] = {
> + PWM_LOOKUP("at91sam9rl-pwm", 0, "leds_pwm", "backlight"),
> +};
> +
> +static struct led_pwm pwm_leds[] = {
> {
> .name = "backlight",
> - .gpio = 0, /* PWM channel 0 (LCD backlight) */
> + .max_brightness = 255,
> + .pwm_period_ns = 5000,
> },
> };
>
> -static struct gpio_led_platform_data stk_pwm_led_data = {
> - .num_leds = ARRAY_SIZE(stk_pwm_led),
> - .leds = stk_pwm_led,
> +static struct led_pwm_platform_data pwm_data = {
> + .num_leds = ARRAY_SIZE(pwm_leds),
> + .leds = pwm_leds,
> };
>
> -static struct platform_device stk_pwm_led_dev = {
> - .name = "leds-atmel-pwm",
> - .id = -1,
> - .dev = {
> - .platform_data = &stk_pwm_led_data,
> +static struct platform_device leds_pwm = {
> + .name = "leds_pwm",
> + .id = -1,
> + .dev = {
> + .platform_data = &pwm_data,
> },
> };
> #endif
> @@ -278,9 +285,10 @@ static int __init merisc_init(void)
>
> at32_add_device_mci(0, &mci0_data);
>
> -#ifdef CONFIG_LEDS_ATMEL_PWM
> +#if IS_ENABLED(CONFIG_LEDS_PWM)
> + pwm_add_table(pwm_lookup, ARRAY_SIZE(pwm_lookup));
> at32_add_device_pwm((1 << 0) | (1 << 2));
> - platform_device_register(&stk_pwm_led_dev);
> + platform_device_register(&leds_pwm);
> #else
> at32_add_device_pwm((1 << 2));
> #endif
--
mvh
Hans-Christian Egtvedt
^ permalink raw reply
* Re: [PATCH 12/16] avr32: favr-32: use generic pwm_bl driver
From: Hans-Christian Egtvedt @ 2014-03-19 14:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1395234209-15546-13-git-send-email-alexandre.belloni@free-electrons.com>
Around Wed 19 Mar 2014 14:03:25 +0100 or thereabout, Alexandre Belloni wrote:
> Switch to the generic pwm_bl driver instead of atmel-pwm-bl.
>
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Acked-by: Hans-Christian Egtvedt <egtvedt@samfundet.no>
I do not have this board either.
> ---
> arch/avr32/boards/favr-32/setup.c | 49 +++++++++++++++++++++++-------------
> arch/avr32/configs/favr-32_defconfig | 6 ++---
> 2 files changed, 34 insertions(+), 21 deletions(-)
>
> diff --git a/arch/avr32/boards/favr-32/setup.c b/arch/avr32/boards/favr-32/setup.c
> index 1f121497b517..391f026705a5 100644
> --- a/arch/avr32/boards/favr-32/setup.c
> +++ b/arch/avr32/boards/favr-32/setup.c
> @@ -18,7 +18,10 @@
> #include <linux/gpio.h>
> #include <linux/leds.h>
> #include <linux/atmel-mci.h>
> -#include <linux/atmel-pwm-bl.h>
> +#include <linux/pwm.h>
> +#include <linux/pwm_backlight.h>
> +#include <linux/regulator/fixed.h>
> +#include <linux/regulator/machine.h>
> #include <linux/spi/spi.h>
> #include <linux/spi/ads7846.h>
>
> @@ -33,6 +36,8 @@
> #include <mach/board.h>
> #include <mach/portmux.h>
>
> +#define PWM_BL_CH 2
> +
> /* Oscillator frequencies. These are board-specific */
> unsigned long at32_board_osc_rates[3] = {
> [0] = 32768, /* 32.768 kHz on RTC osc */
> @@ -227,29 +232,37 @@ void __init favr32_setup_leds(void)
> platform_device_register(&favr32_led_dev);
> }
>
> -static struct atmel_pwm_bl_platform_data atmel_pwm_bl_pdata = {
> - .pwm_channel = 2,
> - .pwm_frequency = 200000,
> - .pwm_compare_max = 345,
> - .pwm_duty_max = 345,
> - .pwm_duty_min = 90,
> - .pwm_active_low = 1,
> - .gpio_on = GPIO_PIN_PA(28),
> - .on_active_low = 0,
> +static struct pwm_lookup pwm_lookup[] = {
> + PWM_LOOKUP("at91sam9rl-pwm", PWM_BL_CH, "pwm-backlight.0", NULL),
> };
>
> -static struct platform_device atmel_pwm_bl_dev = {
> - .name = "atmel-pwm-bl",
> - .id = 0,
> - .dev = {
> - .platform_data = &atmel_pwm_bl_pdata,
> +static struct regulator_consumer_supply fixed_power_consumers[] = {
> + REGULATOR_SUPPLY("power", "pwm-backlight.0"),
> +};
> +
> +static struct platform_pwm_backlight_data pwm_bl_data = {
> + .enable_gpio = GPIO_PIN_PA(28),
> + .pwm_period_ns = 5000,
> + .max_brightness = 255,
> + .dft_brightness = 255,
> + .lth_brightness = 50,
> + .pwm_active_low = true,
> +};
> +
> +static struct platform_device pwm_bl_device = {
> + .name = "pwm-backlight",
> + .dev = {
> + .platform_data = &pwm_bl_data,
> },
> };
>
> static void __init favr32_setup_atmel_pwm_bl(void)
> {
> - platform_device_register(&atmel_pwm_bl_dev);
> - at32_select_gpio(atmel_pwm_bl_pdata.gpio_on, 0);
> + pwm_add_table(pwm_lookup, ARRAY_SIZE(pwm_lookup));
> + regulator_register_always_on(0, "fixed", fixed_power_consumers,
> + ARRAY_SIZE(fixed_power_consumers), 3300000);
> + platform_device_register(&pwm_bl_device);
> + at32_select_gpio(pwm_bl_data.enable_gpio, 0);
> }
>
> void __init setup_board(void)
> @@ -339,7 +352,7 @@ static int __init favr32_init(void)
>
> set_abdac_rate(at32_add_device_abdac(0, &abdac0_data));
>
> - at32_add_device_pwm(1 << atmel_pwm_bl_pdata.pwm_channel);
> + at32_add_device_pwm(1 << PWM_BL_CH);
> at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
> at32_add_device_mci(0, &mci0_data);
> at32_add_device_usba(0, NULL);
> diff --git a/arch/avr32/configs/favr-32_defconfig b/arch/avr32/configs/favr-32_defconfig
> index 07bed3f7eb5e..b3eb67dc05ac 100644
> --- a/arch/avr32/configs/favr-32_defconfig
> +++ b/arch/avr32/configs/favr-32_defconfig
> @@ -67,7 +67,6 @@ CONFIG_MTD_PHYSMAP=y
> CONFIG_BLK_DEV_LOOP=m
> CONFIG_BLK_DEV_NBD=m
> CONFIG_BLK_DEV_RAM=m
> -CONFIG_ATMEL_PWM=m
> CONFIG_ATMEL_TCLIB=y
> CONFIG_ATMEL_SSC=m
> CONFIG_NETDEVICES=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
> @@ -123,7 +122,6 @@ CONFIG_MMC=y
> CONFIG_MMC_ATMELMCI=y
> CONFIG_NEW_LEDS=y
> CONFIG_LEDS_CLASS=y
> -CONFIG_LEDS_ATMEL_PWM=m
> CONFIG_LEDS_GPIO=y
> CONFIG_LEDS_TRIGGERS=y
> CONFIG_LEDS_TRIGGER_TIMER=y
> @@ -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
--
mvh
Hans-Christian Egtvedt
^ permalink raw reply
* Re: [PATCH 13/16] avr32: update defconfig to use the generic PWM framework
From: Hans-Christian Egtvedt @ 2014-03-19 14:21 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1395234209-15546-14-git-send-email-alexandre.belloni@free-electrons.com>
Around Wed 19 Mar 2014 14:03:26 +0100 or thereabout, Alexandre Belloni wrote:
> Now that all boards have switch to the generic PWM framework, update the
> defconfigs to use it.
>
> Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
Acked-by: Hans-Christian Egtvedt <egtvedt@samfundet.no>
> ---
> 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/merisc_defconfig | 5 +++--
> 6 files changed, 18 insertions(+), 12 deletions(-)
<snipp diff>
--
mvh
Hans-Christian Egtvedt
^ permalink raw reply
* Re: [PATCH 14/16] backlight: atmel-pwm-bl: remove obsolete driver
From: Hans-Christian Egtvedt @ 2014-03-19 14:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1395234209-15546-15-git-send-email-alexandre.belloni@free-electrons.com>
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 <alexandre.belloni@free-electrons.com>
Acked-by: Hans-Christian Egtvedt <egtvedt@samfundet.no>
> ---
> 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
<snipp diff>
> -MODULE_AUTHOR("Hans-Christian egtvedt <hans-christian.egtvedt@atmel.com>");
>
sob )':
Great cleanup though.
<snipp diff>
--
mvh
Hans-Christian Egtvedt
^ permalink raw reply
* Re: [PATCH v2] lcd: Provide dummy functions i =?UTF-8?B?ZiBDT05GSUdfTENEX
From: Alexander Shiyan @ 2014-03-20 6:41 UTC (permalink / raw)
To: linux-fbdev
SGVsbG8uCgpXZWQsIDE5IE1hciAyMDE0IDE1OjMxOjQ5ICswMjAwINC+0YIgVG9taSBWYWxrZWlu
ZW4gPHRvbWkudmFsa2VpbmVuQHRpLmNvbT46Cj4gSGksCj4gCj4gT24gMTQvMDMvMTQgMTM6MDks
IEFsZXhhbmRlciBTaGl5YW4gd3JvdGU6Cj4gPiBQcm92aWRlIGR1bW15IGZ1bmN0aW9ucyBmb3Ig
TENEIHJlZ2lzdGVyKCkvdW5yZWdpc3RlcigpIGlmCj4gPiBDT05GSUdfTENEX0NMQVNTX0RFVklD
RSBpcyBub3Qgc2V0Lgo+ID4gVGhpcyBhbGxvd3MgdXMgdG8gdXNlIHRoZSBMQ0QgY2xhc3MgYXMg
YW4gb3B0aW9uYWwuCj4gPiAKPiA+IFNpZ25lZC1vZmYtYnk6IEFsZXhhbmRlciBTaGl5YW4gPHNo
Y193b3JrQG1haWwucnU+Cj4gPiAtLS0KPiA+ICBpbmNsdWRlL2xpbnV4L2xjZC5oIHwgMzcgKysr
KysrKysrKysrKysrKysrKysrKysrKysrKysrLS0tLS0tLQo+ID4gIDEgZmlsZSBjaGFuZ2VkLCAz
MCBpbnNlcnRpb25zKCspLCA3IGRlbGV0aW9ucygtKQo+IAo+IEknbSBzdGlsbCBub3QgY29udmlu
Y2VkIGFib3V0IHRoaXMuIElzbid0IGl0IHNpbXBsZXIgdG8ganVzdAo+IHNlbGVjdC9kZXBlbmQg
b24gTENEX0NMQVNTX0RFVklDRT8gVGhlIGxjZC5jIGlzIGEgYml0IGxlc3MgdGhhbiA5IGtCLCBz
bwo+IGl0J3Mgbm90IGxpa2UgeW91J3JlIGFkZGluZyBhIGh1Z2UgYW1vdW50IG9mIGNvZGUgaW50
byB0aGUga2VybmVsIGV2ZW4KPiBpZiB0aGUgZHJpdmVyIGRvZXNuJ3QgaGFwcGVuIHRvIHVzZSBp
dCBmb3IgYSBwYXJ0aWN1bGFyIGRpc3BsYXkuCgpJZSB3ZSBwcmVmZXIgdG8gaW5jcmVhc2UgdGhl
IHNpemUgb2YgdGhlIGtlcm5lbCwgZXZlbiBmb3IgZnVuY3Rpb25zIHdoaWNoIGFyZSBvcHRpb25h
bD8KT0ssIEknbGwgcG9zdCBhIHBhdGNoIGZvciB0aGUgaW14ZmIgZHJpdmVyIHdoaWNoIHNlbGVj
dHMgTENEX0NMQVNTIHVuY29uZGl0aW9uYWxseS4KTmV2ZXJ0aGVsZXNzLCB0aGUgY3VycmVudCBw
YXRjaCBpcyBzdGlsbCB2YWxpZCBmb3IgcmV2aWV3LgoKVGhhbmtzLgotLS0KCg=
^ permalink raw reply
* [PATCH] video: imxfb: Select LCD_CLASS_DEVICE unconditionally
From: Alexander Shiyan @ 2014-03-20 6:58 UTC (permalink / raw)
To: linux-fbdev
FB driver uses lowlevel controls for LCD powering and contrast changing.
Since LCD class cannot be used as an optional feature and should be
compiled for using in the driver, this patch selects LCD_CLASS_DEVICE
symbol for the driver.
Signed-off-by: Alexander Shiyan <shc_work@mail.ru>
---
drivers/video/fbdev/Kconfig | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 67409e0..b7cb0af 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -328,6 +328,8 @@ config FB_SA1100
config FB_IMX
tristate "Freescale i.MX1/21/25/27 LCD support"
depends on FB && IMX_HAVE_PLATFORM_IMX_FB
+ select BACKLIGHT_LCD_SUPPORT
+ select LCD_CLASS_DEVICE
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
--
1.8.3.2
^ permalink raw reply related
* Re: [PATCH v2] lcd: Provide dummy functions if CONFIG_LCD_CLASS_DEVICE is not set
From: Tomi Valkeinen @ 2014-03-20 7:08 UTC (permalink / raw)
To: linux-fbdev
In-Reply-To: <1394795353-1931-1-git-send-email-shc_work@mail.ru>
[-- Attachment #1: Type: text/plain, Size: 2256 bytes --]
On 20/03/14 08:41, Alexander Shiyan wrote:
> Hello.
>
> Wed, 19 Mar 2014 15:31:49 +0200 от Tomi Valkeinen <tomi.valkeinen@ti.com>:
>> Hi,
>>
>> On 14/03/14 13:09, Alexander Shiyan wrote:
>>> Provide dummy functions for LCD register()/unregister() if
>>> CONFIG_LCD_CLASS_DEVICE is not set.
>>> This allows us to use the LCD class as an optional.
>>>
>>> Signed-off-by: Alexander Shiyan <shc_work@mail.ru>
>>> ---
>>> include/linux/lcd.h | 37 ++++++++++++++++++++++++++++++-------
>>> 1 file changed, 30 insertions(+), 7 deletions(-)
>>
>> I'm still not convinced about this. Isn't it simpler to just
>> select/depend on LCD_CLASS_DEVICE? The lcd.c is a bit less than 9 kB, so
>> it's not like you're adding a huge amount of code into the kernel even
>> if the driver doesn't happen to use it for a particular display.
>
> Ie we prefer to increase the size of the kernel, even for functions which are optional?
How often can LCD_CLASS_DEVICE be turned off when using imxfb? How often
will it be turned off in practice? I fear this is a micro optimization
for cases that never happen in real life.
I'm fine with micro optimizing the kernel when it comes for free. In
this case I see drawback: usually (correct me if I'm wrong) if a fb
driver uses LCD_CLASS_DEVICE funcs, it requires it. Currently it's easy
to catch missing LCD_CLASS_DEVICE as the kernel won't compile. This
patch hides it until you try to run the driver. And compile time
checking is much, much better than runtime checking.
We have components that use the method you use in this patch, like
gpio.h. However, the difference with gpio and this one is that the
selection of gpio comes from the platform code, while the
LCD_CLASS_DEVICE is selected by the fb driver in question. So the fb
driver can easily select LCD_CLASS_DEVICE, while it cannot select GPIO.
My point here is that for gpios we more or less need such functionality,
whereas for LCD_CLASS_DEVICE we don't.
I'm not strongly against this patch. But, as I said, I see a small
drawback with it, so I'd like to either hear "yes, this is good" from
other people, or see information showing that this optimization will
actually help in lots of cases in real life.
Tomi
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 901 bytes --]
^ permalink raw reply
* [PATCH] drivers/video: fix mb862xx_i2c depends issue build failure
From: Paul Gortmaker @ 2014-03-20 15:16 UTC (permalink / raw)
To: Jean-Christophe Plagniol-Villard, Tomi Valkeinen
Cc: linux-fbdev, linux-kernel, Jim Davis, Fengguang Wu,
Paul Gortmaker
Any randconfig that sets I2C=m and FB_MB862XX_I2C=y will
encounter a final link failure that looks like this:
drivers/built-in.o: In function `mb862xx_i2c_init':
drivers/video/mb862xx/mb862xx-i2c.c:165: undefined reference to `i2c_add_adapter'
drivers/built-in.o: In function `mb862xx_i2c_exit':
drivers/video/mb862xx/mb862xx-i2c.c:176: undefined reference to `i2c_del_adapter'
Since FB_MB862XX_I2C is a bool and not tristate, simply
don't offer it at all if core I2C support is not built in.
Reported-by: Jim Davis <jim.epost@gmail.com>
Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index dade5b7699bc..aefd1b9a3cbd 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -2338,7 +2338,7 @@ endchoice
config FB_MB862XX_I2C
bool "Support I2C bus on MB862XX GDC"
- depends on FB_MB862XX && I2C
+ depends on FB_MB862XX && I2C=y
default y
help
Selecting this option adds Coral-P(A)/Lime GDC I2C bus adapter
--
1.9.0
^ permalink raw reply related
* [PATCH 0/3] video: clps711x: New CLPS711X FB driver
From: Alexander Shiyan @ 2014-03-20 16:24 UTC (permalink / raw)
To: linux-fbdev
This series adds a new framebuffer driver for Cirrus Logic CLPS711X
CPUs. Since all code rewritten from scratch, patch is designed as a
replacement of the old (not updated for a long time) for a new one.
The second part of the patch affects changes for the ARM CLPS711X
core subsystem, so ACK from the ARM maintainers would be useful.
Patch originally designed for apply to the video subsystem, but I
have no prejudice it and if it will be applied to the arm-soc branch,
this will also be good.
Alexander Shiyan (3):
video: clps711x: Add new Cirrus Logic CLPS711X framebuffer driver
video: clps711x: Switch CLPS711X boards to use new FB driver
video: clps711x: Add bindings documentation for CLPS711X framebuffer
.../bindings/video/cirrus,clps711x-fb.txt | 48 +++
arch/arm/mach-clps711x/board-autcpu12.c | 2 +-
arch/arm/mach-clps711x/board-edb7211.c | 2 +-
arch/arm/mach-clps711x/board-p720t.c | 2 +-
arch/arm/mach-clps711x/devices.c | 17 +
arch/arm/mach-clps711x/devices.h | 1 +
drivers/video/fbdev/Kconfig | 18 +-
drivers/video/fbdev/Makefile | 2 +-
drivers/video/fbdev/clps711x-fb.c | 456 +++++++++++++++++++++
drivers/video/fbdev/clps711xfb.c | 315 --------------
10 files changed, 537 insertions(+), 326 deletions(-)
create mode 100644 Documentation/devicetree/bindings/video/cirrus,clps711x-fb.txt
create mode 100644 drivers/video/fbdev/clps711x-fb.c
delete mode 100644 drivers/video/fbdev/clps711xfb.c
--
1.8.3.2
^ permalink raw reply
* [PATCH 1/3] video: clps711x: Add new Cirrus Logic CLPS711X framebuffer driver
From: Alexander Shiyan @ 2014-03-20 16:24 UTC (permalink / raw)
To: linux-fbdev
This adds support for the framebuffer available in the Cirrus
Logic CLPS711X CPUs.
The driver have been tested with custom board equipped Cirrus Logic
EP7312 in DT and non-DT mode.
Signed-off-by: Alexander Shiyan <shc_work@mail.ru>
---
drivers/video/fbdev/clps711x-fb.c | 456 ++++++++++++++++++++++++++++++++++++++
1 file changed, 456 insertions(+)
create mode 100644 drivers/video/fbdev/clps711x-fb.c
diff --git a/drivers/video/fbdev/clps711x-fb.c b/drivers/video/fbdev/clps711x-fb.c
new file mode 100644
index 0000000..87fd42d
--- /dev/null
+++ b/drivers/video/fbdev/clps711x-fb.c
@@ -0,0 +1,456 @@
+/*
+ * Cirrus Logic CLPS711X FB driver
+ *
+ * Copyright (C) 2014 Alexander Shiyan <shc_work@mail.ru>
+ * Based on driver by Russell King <rmk@arm.linux.org.uk>
+ *
+ * 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 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/clk.h>
+#include <linux/fb.h>
+#include <linux/io.h>
+#include <linux/lcd.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mfd/syscon/clps711x.h>
+#include <linux/regulator/consumer.h>
+#include <video/of_display_timing.h>
+
+#define CLPS711X_FB_NAME "clps711x-fb"
+#define CLPS711X_FB_BPP_MAX (4)
+
+/* Registers relative to LCDCON */
+#define CLPS711X_LCDCON (0x0000)
+# define LCDCON_GSEN BIT(30)
+# define LCDCON_GSMD BIT(31)
+#define CLPS711X_PALLSW (0x0280)
+#define CLPS711X_PALMSW (0x02c0)
+#define CLPS711X_FBADDR (0x0d40)
+
+struct clps711x_fb_info {
+ struct clk *clk;
+ void __iomem *base;
+ struct regmap *syscon;
+ resource_size_t buffsize;
+ struct fb_videomode mode;
+ struct regulator *lcd_pwr;
+ u32 ac_prescale;
+ bool cmap_invert;
+};
+
+static int clps711x_fb_setcolreg(u_int regno, u_int red, u_int green,
+ u_int blue, u_int transp, struct fb_info *info)
+{
+ struct clps711x_fb_info *cfb = info->par;
+ u32 level, mask, shift;
+
+ if (regno >= BIT(info->var.bits_per_pixel))
+ return -EINVAL;
+
+ shift = 4 * (regno & 7);
+ mask = 0xf << shift;
+ /* gray = 0.30*R + 0.58*G + 0.11*B */
+ level = (((red * 77 + green * 151 + blue * 28) >> 20) << shift) & mask;
+ if (cfb->cmap_invert)
+ level = 0xf - level;
+
+ regno = (regno < 8) ? CLPS711X_PALLSW : CLPS711X_PALMSW;
+
+ writel((readl(cfb->base + regno) & ~mask) | level, cfb->base + regno);
+
+ return 0;
+}
+
+static int clps711x_fb_check_var(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ u32 val;
+
+ if (var->bits_per_pixel < 1 ||
+ var->bits_per_pixel > CLPS711X_FB_BPP_MAX)
+ return -EINVAL;
+
+ if (!var->pixclock)
+ return -EINVAL;
+
+ val = DIV_ROUND_UP(var->xres, 16) - 1;
+ if (val < 0x01 || val > 0x3f)
+ return -EINVAL;
+
+ val = DIV_ROUND_UP(var->yres * var->xres * var->bits_per_pixel, 128);
+ val--;
+ if (val < 0x001 || val > 0x1fff)
+ return -EINVAL;
+
+ var->transp.msb_right = 0;
+ var->transp.offset = 0;
+ var->transp.length = 0;
+ var->red.msb_right = 0;
+ var->red.offset = 0;
+ var->red.length = var->bits_per_pixel;
+ var->green = var->red;
+ var->blue = var->red;
+ var->grayscale = var->bits_per_pixel > 1;
+
+ return 0;
+}
+
+static int clps711x_fb_set_par(struct fb_info *info)
+{
+ struct clps711x_fb_info *cfb = info->par;
+ resource_size_t size;
+ u32 lcdcon, pps;
+
+ size = (info->var.xres * info->var.yres * info->var.bits_per_pixel) / 8;
+ if (size > cfb->buffsize)
+ return -EINVAL;
+
+ switch (info->var.bits_per_pixel) {
+ case 1:
+ info->fix.visual = FB_VISUAL_MONO01;
+ break;
+ case 2:
+ case 4:
+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ info->fix.line_length = info->var.xres * info->var.bits_per_pixel / 8;
+ info->fix.smem_len = size;
+
+ lcdcon = (info->var.xres * info->var.yres *
+ info->var.bits_per_pixel) / 128 - 1;
+ lcdcon |= ((info->var.xres / 16) - 1) << 13;
+ lcdcon |= (cfb->ac_prescale & 0x1f) << 25;
+
+ pps = clk_get_rate(cfb->clk) / (PICOS2KHZ(info->var.pixclock) * 1000);
+ if (pps)
+ pps--;
+ lcdcon |= (pps & 0x3f) << 19;
+
+ if (info->var.bits_per_pixel = 4)
+ lcdcon |= LCDCON_GSMD;
+ if (info->var.bits_per_pixel >= 2)
+ lcdcon |= LCDCON_GSEN;
+
+ /* LCDCON must only be changed while the LCD is disabled */
+ regmap_update_bits(cfb->syscon, SYSCON_OFFSET, SYSCON1_LCDEN, 0);
+ writel(lcdcon, cfb->base + CLPS711X_LCDCON);
+ regmap_update_bits(cfb->syscon, SYSCON_OFFSET,
+ SYSCON1_LCDEN, SYSCON1_LCDEN);
+
+ return 0;
+}
+
+static int clps711x_fb_blank(int blank, struct fb_info *info)
+{
+ /* Return happy */
+ return 0;
+}
+
+static struct fb_ops clps711x_fb_ops = {
+ .owner = THIS_MODULE,
+ .fb_setcolreg = clps711x_fb_setcolreg,
+ .fb_check_var = clps711x_fb_check_var,
+ .fb_set_par = clps711x_fb_set_par,
+ .fb_blank = clps711x_fb_blank,
+ .fb_fillrect = sys_fillrect,
+ .fb_copyarea = sys_copyarea,
+ .fb_imageblit = sys_imageblit,
+};
+
+static int clps711x_lcd_check_fb(struct lcd_device *lcddev, struct fb_info *fi)
+{
+ struct clps711x_fb_info *cfb = dev_get_drvdata(&lcddev->dev);
+
+ return (!fi || fi->par = cfb) ? 1 : 0;
+}
+
+static int clps711x_lcd_get_power(struct lcd_device *lcddev)
+{
+ struct clps711x_fb_info *cfb = dev_get_drvdata(&lcddev->dev);
+
+ if (!IS_ERR_OR_NULL(cfb->lcd_pwr))
+ return regulator_is_enabled(cfb->lcd_pwr);
+
+ return 1;
+}
+
+static int clps711x_lcd_set_power(struct lcd_device *lcddev, int power)
+{
+ struct clps711x_fb_info *cfb = dev_get_drvdata(&lcddev->dev);
+
+ if (!IS_ERR_OR_NULL(cfb->lcd_pwr)) {
+ if (power)
+ return regulator_enable(cfb->lcd_pwr);
+ else
+ return regulator_disable(cfb->lcd_pwr);
+ }
+
+ return 0;
+}
+
+static struct lcd_ops clps711x_lcd_ops = {
+ .check_fb = clps711x_lcd_check_fb,
+ .get_power = clps711x_lcd_get_power,
+ .set_power = clps711x_lcd_set_power,
+};
+
+static int clps711x_fb_get_mode(struct platform_device *pdev)
+{
+ struct fb_info *info = platform_get_drvdata(pdev);
+ bool *pinvert = dev_get_platdata(&pdev->dev);
+ struct clps711x_fb_info *cfb = info->par;
+ unsigned long pixclk;
+ unsigned int val;
+ int ret;
+
+ cfb->syscon = syscon_regmap_lookup_by_pdevname("syscon.1");
+ if (IS_ERR(cfb->syscon))
+ return PTR_ERR(cfb->syscon);
+
+ ret = regmap_read(cfb->syscon, SYSCON_OFFSET, &val);
+ if (ret)
+ return ret;
+
+ if (pinvert)
+ cfb->cmap_invert = *pinvert;
+
+ /* Get mode from LCD if active */
+ if (val & SYSCON1_LCDEN) {
+ val = readl(cfb->base + CLPS711X_LCDCON);
+
+ switch (val & (LCDCON_GSMD | LCDCON_GSEN)) {
+ case LCDCON_GSMD | LCDCON_GSEN:
+ info->var.bits_per_pixel = 4;
+ break;
+ case LCDCON_GSEN:
+ info->var.bits_per_pixel = 2;
+ break;
+ default:
+ info->var.bits_per_pixel = 1;
+ break;
+ }
+
+ cfb->mode.xres = (((val >> 13) & 0x3f) + 1) * 16;
+ cfb->mode.yres = (((val & 0x1fff) + 1) * 128) /
+ (cfb->mode.xres * info->var.bits_per_pixel);
+ cfb->ac_prescale = (val >> 25) & 0x1f;
+ pixclk = clk_get_rate(cfb->clk) / (((val >> 19) & 0x3f) + 1);
+ } else {
+ /* Fixed setup for existing users */
+ info->var.bits_per_pixel = 4;
+ cfb->mode.xres = 640;
+ cfb->mode.yres = 240;
+ cfb->ac_prescale = 13;
+ pixclk = 10000000;
+ }
+
+ cfb->mode.refresh = pixclk / (cfb->mode.xres * cfb->mode.yres);
+ cfb->mode.pixclock = KHZ2PICOS(pixclk / 1000);
+
+ return 0;
+}
+
+static int clps711x_fb_get_mode_dt(struct platform_device *pdev)
+{
+ struct device_node *disp, *np = pdev->dev.of_node;
+ struct fb_info *info = platform_get_drvdata(pdev);
+ struct clps711x_fb_info *cfb = info->par;
+ int ret;
+
+ cfb->syscon + syscon_regmap_lookup_by_compatible("cirrus,clps711x-syscon1");
+ if (IS_ERR(cfb->syscon))
+ return PTR_ERR(cfb->syscon);
+
+ disp = of_parse_phandle(np, "display", 0);
+ if (!disp) {
+ dev_err(&pdev->dev, "No display defined\n");
+ return -ENODATA;
+ }
+
+ ret = of_get_fb_videomode(disp, &cfb->mode, OF_USE_NATIVE_MODE);
+ if (ret)
+ return ret;
+
+ of_property_read_u32(disp, "ac-prescale", &cfb->ac_prescale);
+ cfb->cmap_invert = of_property_read_bool(disp, "cmap-invert");
+
+ return of_property_read_u32(disp, "bits-per-pixel",
+ &info->var.bits_per_pixel);
+}
+
+static int clps711x_fb_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct device_node *np = dev->of_node;
+ struct clps711x_fb_info *cfb;
+ struct lcd_device *lcd;
+ struct fb_info *info;
+ struct resource *res;
+ int ret = -ENOENT;
+ u32 val;
+
+ if (fb_get_options(CLPS711X_FB_NAME, NULL))
+ return -ENODEV;
+
+ info = framebuffer_alloc(sizeof(*cfb), dev);
+ if (!info)
+ return -ENOMEM;
+
+ cfb = info->par;
+ platform_set_drvdata(pdev, info);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ goto out_fb_release;
+ cfb->base = devm_ioremap(dev, res->start, resource_size(res));
+ if (!cfb->base) {
+ ret = -ENOMEM;
+ goto out_fb_release;
+ }
+
+ info->fix.mmio_start = res->start;
+ info->fix.mmio_len = resource_size(res);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ info->screen_base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(info->screen_base)) {
+ ret = PTR_ERR(info->screen_base);
+ goto out_fb_release;
+ }
+
+ /* Physical address should be aligned to 256 MiB */
+ if (res->start & 0x0fffffff) {
+ ret = -EINVAL;
+ goto out_fb_release;
+ }
+
+ info->apertures = alloc_apertures(1);
+ if (!info->apertures) {
+ ret = -ENOMEM;
+ goto out_fb_release;
+ }
+
+ cfb->buffsize = resource_size(res);
+ info->fix.smem_start = res->start;
+ info->apertures->ranges[0].base = info->fix.smem_start;
+ info->apertures->ranges[0].size = cfb->buffsize;
+
+ cfb->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(cfb->clk)) {
+ ret = PTR_ERR(cfb->clk);
+ goto out_fb_release;
+ }
+
+ ret = np ? clps711x_fb_get_mode_dt(pdev) : clps711x_fb_get_mode(pdev);
+ if (ret)
+ goto out_fb_release;
+
+ /* Force disable LCD on any mismatch */
+ if (info->fix.smem_start != (readb(cfb->base + CLPS711X_FBADDR) << 28))
+ regmap_update_bits(cfb->syscon, SYSCON_OFFSET,
+ SYSCON1_LCDEN, 0);
+
+ ret = regmap_read(cfb->syscon, SYSCON_OFFSET, &val);
+ if (ret)
+ goto out_fb_release;
+
+ if (!(val & SYSCON1_LCDEN)) {
+ /* Setup start FB address */
+ writeb(info->fix.smem_start >> 28, cfb->base + CLPS711X_FBADDR);
+ /* Clean FB memory */
+ memset(info->screen_base, 0, cfb->buffsize);
+ }
+
+ cfb->lcd_pwr = devm_regulator_get(dev, "lcd");
+ if (PTR_ERR(cfb->lcd_pwr) = -EPROBE_DEFER) {
+ ret = -EPROBE_DEFER;
+ goto out_fb_release;
+ }
+
+ info->fbops = &clps711x_fb_ops;
+ info->flags = FBINFO_DEFAULT;
+ info->var.activate = FB_ACTIVATE_FORCE | FB_ACTIVATE_NOW;
+ info->var.height = -1;
+ info->var.width = -1;
+ info->var.vmode = FB_VMODE_NONINTERLACED;
+ info->fix.type = FB_TYPE_PACKED_PIXELS;
+ info->fix.accel = FB_ACCEL_NONE;
+ strlcpy(info->fix.id, CLPS711X_FB_NAME, sizeof(info->fix.id));
+ fb_videomode_to_var(&info->var, &cfb->mode);
+
+ ret = fb_alloc_cmap(&info->cmap, BIT(CLPS711X_FB_BPP_MAX), 0);
+ if (ret)
+ goto out_fb_release;
+
+ ret = fb_set_var(info, &info->var);
+ if (ret)
+ goto out_fb_dealloc_cmap;
+
+ ret = register_framebuffer(info);
+ if (ret)
+ goto out_fb_dealloc_cmap;
+
+ lcd = devm_lcd_device_register(dev, "clps711x-lcd", dev, cfb,
+ &clps711x_lcd_ops);
+ if (!IS_ERR(lcd))
+ return 0;
+
+ ret = PTR_ERR(lcd);
+ unregister_framebuffer(info);
+
+out_fb_dealloc_cmap:
+ regmap_update_bits(cfb->syscon, SYSCON_OFFSET, SYSCON1_LCDEN, 0);
+ fb_dealloc_cmap(&info->cmap);
+
+out_fb_release:
+ framebuffer_release(info);
+
+ return ret;
+}
+
+static int clps711x_fb_remove(struct platform_device *pdev)
+{
+ struct fb_info *info = platform_get_drvdata(pdev);
+ struct clps711x_fb_info *cfb = info->par;
+
+ regmap_update_bits(cfb->syscon, SYSCON_OFFSET, SYSCON1_LCDEN, 0);
+
+ unregister_framebuffer(info);
+ fb_dealloc_cmap(&info->cmap);
+ framebuffer_release(info);
+
+ return 0;
+}
+
+static const struct of_device_id __maybe_unused clps711x_fb_dt_ids[] = {
+ { .compatible = "cirrus,clps711x-fb", },
+ { }
+};
+MODULE_DEVICE_TABLE(of, clps711x_fb_dt_ids);
+
+static struct platform_driver clps711x_fb_driver = {
+ .driver = {
+ .name = CLPS711X_FB_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(clps711x_fb_dt_ids),
+ },
+ .probe = clps711x_fb_probe,
+ .remove = clps711x_fb_remove,
+};
+module_platform_driver(clps711x_fb_driver);
+
+MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>");
+MODULE_DESCRIPTION("Cirrus Logic CLPS711X FB driver");
+MODULE_LICENSE("GPL");
--
1.8.3.2
^ permalink raw reply related
* [PATCH 2/3] video: clps711x: Switch CLPS711X boards to use new FB driver
From: Alexander Shiyan @ 2014-03-20 16:24 UTC (permalink / raw)
To: linux-fbdev
This patch removes old implementation of Cirrus Logic CLPS711X FB
driver and switch current users to use new one.
Signed-off-by: Alexander Shiyan <shc_work@mail.ru>
---
arch/arm/mach-clps711x/board-autcpu12.c | 2 +-
arch/arm/mach-clps711x/board-edb7211.c | 2 +-
arch/arm/mach-clps711x/board-p720t.c | 2 +-
arch/arm/mach-clps711x/devices.c | 17 ++
arch/arm/mach-clps711x/devices.h | 1 +
drivers/video/fbdev/Kconfig | 18 +-
drivers/video/fbdev/Makefile | 2 +-
drivers/video/fbdev/clps711xfb.c | 315 --------------------------------
8 files changed, 33 insertions(+), 326 deletions(-)
delete mode 100644 drivers/video/fbdev/clps711xfb.c
diff --git a/arch/arm/mach-clps711x/board-autcpu12.c b/arch/arm/mach-clps711x/board-autcpu12.c
index d62ca16..c63f872 100644
--- a/arch/arm/mach-clps711x/board-autcpu12.c
+++ b/arch/arm/mach-clps711x/board-autcpu12.c
@@ -249,7 +249,7 @@ static void __init autcpu12_init(void)
{
clps711x_devices_init();
platform_device_register(&autcpu12_flash_pdev);
- platform_device_register_simple("video-clps711x", 0, NULL, 0);
+ clps711x_add_fb(CLPS711X_SRAM_BASE, CLPS711X_SRAM_SIZE);
platform_device_register_simple("cs89x0", 0, autcpu12_cs8900_resource,
ARRAY_SIZE(autcpu12_cs8900_resource));
platform_device_register(&autcpu12_mmgpio_pdev);
diff --git a/arch/arm/mach-clps711x/board-edb7211.c b/arch/arm/mach-clps711x/board-edb7211.c
index 0776098..d9293a0 100644
--- a/arch/arm/mach-clps711x/board-edb7211.c
+++ b/arch/arm/mach-clps711x/board-edb7211.c
@@ -166,7 +166,7 @@ static void __init edb7211_init_late(void)
platform_device_register_data(&platform_bus, "generic-bl", 0,
&edb7211_lcd_backlight_pdata,
sizeof(edb7211_lcd_backlight_pdata));
- platform_device_register_simple("video-clps711x", 0, NULL, 0);
+ clps711x_add_fb(CLPS711X_SDRAM0_BASE, VIDEORAM_SIZE);
platform_device_register_simple("cs89x0", 0, edb7211_cs8900_resource,
ARRAY_SIZE(edb7211_cs8900_resource));
platform_device_register_data(&platform_bus, "i2c-gpio", 0,
diff --git a/arch/arm/mach-clps711x/board-p720t.c b/arch/arm/mach-clps711x/board-p720t.c
index 67b7337..5bc4fa4 100644
--- a/arch/arm/mach-clps711x/board-p720t.c
+++ b/arch/arm/mach-clps711x/board-p720t.c
@@ -354,7 +354,7 @@ static void __init p720t_init_late(void)
platform_device_register_data(&platform_bus, "generic-bl", 0,
&p720t_lcd_backlight_pdata,
sizeof(p720t_lcd_backlight_pdata));
- platform_device_register_simple("video-clps711x", 0, NULL, 0);
+ clps711x_add_fb(CLPS711X_SRAM_BASE, CLPS711X_SRAM_SIZE);
platform_device_register_data(&platform_bus, "leds-gpio", 0,
&p720t_gpio_led_pdata,
sizeof(p720t_gpio_led_pdata));
diff --git a/arch/arm/mach-clps711x/devices.c b/arch/arm/mach-clps711x/devices.c
index 2001488..f644d35 100644
--- a/arch/arm/mach-clps711x/devices.c
+++ b/arch/arm/mach-clps711x/devices.c
@@ -14,6 +14,23 @@
#include <mach/hardware.h>
+void __init clps711x_add_fb(phys_addr_t base, resource_size_t size)
+{
+ struct resource res[2];
+
+ memset(res, 0, sizeof(res));
+
+ res[0].flags = IORESOURCE_MEM;
+ res[0].start = CLPS711X_PHYS_BASE + LCDCON;
+ res[0].end = CLPS711X_PHYS_BASE + FBADDR + 3;
+ res[1].flags = IORESOURCE_MEM;
+ res[1].start = base;
+ res[1].end = base + size - 1;
+
+ platform_device_register_simple("clps711x-fb", PLATFORM_DEVID_NONE,
+ res, ARRAY_SIZE(res));
+}
+
static const phys_addr_t clps711x_gpios[][2] __initconst = {
{ PADR, PADDR },
{ PBDR, PBDDR },
diff --git a/arch/arm/mach-clps711x/devices.h b/arch/arm/mach-clps711x/devices.h
index a5efc17..01e7f45 100644
--- a/arch/arm/mach-clps711x/devices.h
+++ b/arch/arm/mach-clps711x/devices.h
@@ -9,4 +9,5 @@
* (at your option) any later version.
*/
+void clps711x_add_fb(phys_addr_t, resource_size_t);
void clps711x_devices_init(void);
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 45fd7f3..d1f6dca 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -302,14 +302,18 @@ config FB_ACORN
unsure, say N.
config FB_CLPS711X
- bool "CLPS711X LCD support"
- depends on (FB = y) && ARM && ARCH_CLPS711X
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
+ tristate "CLPS711X LCD support"
+ depends on FB && (ARCH_CLPS711X || COMPILE_TEST)
+ select BACKLIGHT_LCD_SUPPORT
+ select FB_MODE_HELPERS
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select LCD_CLASS_DEVICE
+ select VIDEOMODE_HELPERS
help
- Say Y to enable the Framebuffer driver for the CLPS7111 and
- EP7212 processors.
+ Say Y to enable the Framebuffer driver for the Cirrus Logic
+ CLPS711X CPUs.
config FB_SA1100
bool "SA-1100 LCD support"
diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile
index 0284f2a..0164bb1 100644
--- a/drivers/video/fbdev/Makefile
+++ b/drivers/video/fbdev/Makefile
@@ -14,7 +14,7 @@ obj-$(CONFIG_FB_WMT_GE_ROPS) += wmt_ge_rops.o
# Hardware specific drivers go first
obj-$(CONFIG_FB_AMIGA) += amifb.o c2p_planar.o
obj-$(CONFIG_FB_ARC) += arcfb.o
-obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o
+obj-$(CONFIG_FB_CLPS711X) += clps711x-fb.o
obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o
obj-$(CONFIG_FB_GRVGA) += grvga.o
obj-$(CONFIG_FB_PM2) += pm2fb.o
diff --git a/drivers/video/fbdev/clps711xfb.c b/drivers/video/fbdev/clps711xfb.c
deleted file mode 100644
index f009806..0000000
--- a/drivers/video/fbdev/clps711xfb.c
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * linux/drivers/video/clps711xfb.c
- *
- * Copyright (C) 2000-2001 Deep Blue Solutions Ltd.
- *
- * 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 of the License, 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; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * Framebuffer driver for the CLPS7111 and EP7212 processors.
- */
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-
-#include <mach/hardware.h>
-#include <asm/mach-types.h>
-#include <linux/uaccess.h>
-
-struct fb_info *cfb;
-
-#define CMAP_MAX_SIZE 16
-
-/*
- * LCD AC Prescale. This comes from the LCD panel manufacturers specifications.
- * This determines how many clocks + 1 of CL1 before the M signal toggles.
- * The number of lines on the display must not be divisible by this number.
- */
-static unsigned int lcd_ac_prescale = 13;
-
-/*
- * Set a single color register. Return != 0 for invalid regno.
- */
-static int
-clps7111fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
- u_int transp, struct fb_info *info)
-{
- unsigned int level, mask, shift, pal;
-
- if (regno >= (1 << info->var.bits_per_pixel))
- return 1;
-
- /* gray = 0.30*R + 0.58*G + 0.11*B */
- level = (red * 77 + green * 151 + blue * 28) >> 20;
-
- /*
- * On an LCD, a high value is dark, while a low value is light.
- * So we invert the level.
- *
- * This isn't true on all machines, so we only do it on EDB7211.
- * --rmk
- */
- if (machine_is_edb7211()) {
- level = 15 - level;
- }
-
- shift = 4 * (regno & 7);
- level <<= shift;
- mask = 15 << shift;
- level &= mask;
-
- regno = regno < 8 ? PALLSW : PALMSW;
-
- pal = clps_readl(regno);
- pal = (pal & ~mask) | level;
- clps_writel(pal, regno);
-
- return 0;
-}
-
-/*
- * Validate the purposed mode.
- */
-static int
-clps7111fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
-{
- var->transp.msb_right = 0;
- var->transp.offset = 0;
- var->transp.length = 0;
- var->red.msb_right = 0;
- var->red.offset = 0;
- var->red.length = var->bits_per_pixel;
- var->green = var->red;
- var->blue = var->red;
-
- if (var->bits_per_pixel > 4)
- return -EINVAL;
-
- return 0;
-}
-
-/*
- * Set the hardware state.
- */
-static int
-clps7111fb_set_par(struct fb_info *info)
-{
- unsigned int lcdcon, syscon, pixclock;
-
- switch (info->var.bits_per_pixel) {
- case 1:
- info->fix.visual = FB_VISUAL_MONO01;
- break;
- case 2:
- info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
- break;
- case 4:
- info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
- break;
- }
-
- info->fix.line_length = info->var.xres_virtual * info->var.bits_per_pixel / 8;
-
- lcdcon = (info->var.xres_virtual * info->var.yres_virtual * info->var.bits_per_pixel) / 128 - 1;
- lcdcon |= ((info->var.xres_virtual / 16) - 1) << 13;
- lcdcon |= lcd_ac_prescale << 25;
-
- /*
- * Calculate pixel prescale value from the pixclock. This is:
- * 36.864MHz / pixclock_mhz - 1.
- * However, pixclock is in picoseconds, so this ends up being:
- * 36864000 * pixclock_ps / 10^12 - 1
- * and this will overflow the 32-bit math. We perform this as
- * (9 * 4096000 = 36864000):
- * pixclock_ps * 9 * (4096000 / 10^12) - 1
- */
- pixclock = 9 * info->var.pixclock / 244140 - 1;
- lcdcon |= pixclock << 19;
-
- if (info->var.bits_per_pixel = 4)
- lcdcon |= LCDCON_GSMD;
- if (info->var.bits_per_pixel >= 2)
- lcdcon |= LCDCON_GSEN;
-
- /*
- * LCDCON must only be changed while the LCD is disabled
- */
- syscon = clps_readl(SYSCON1);
- clps_writel(syscon & ~SYSCON1_LCDEN, SYSCON1);
- clps_writel(lcdcon, LCDCON);
- clps_writel(syscon | SYSCON1_LCDEN, SYSCON1);
- return 0;
-}
-
-static int clps7111fb_blank(int blank, struct fb_info *info)
-{
- /* Enable/Disable LCD controller. */
- if (blank)
- clps_writel(clps_readl(SYSCON1) & ~SYSCON1_LCDEN, SYSCON1);
- else
- clps_writel(clps_readl(SYSCON1) | SYSCON1_LCDEN, SYSCON1);
-
- return 0;
-}
-
-static struct fb_ops clps7111fb_ops = {
- .owner = THIS_MODULE,
- .fb_check_var = clps7111fb_check_var,
- .fb_set_par = clps7111fb_set_par,
- .fb_setcolreg = clps7111fb_setcolreg,
- .fb_blank = clps7111fb_blank,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
- .fb_imageblit = cfb_imageblit,
-};
-
-static void clps711x_guess_lcd_params(struct fb_info *info)
-{
- unsigned int lcdcon, syscon, size;
- unsigned long phys_base = PAGE_OFFSET;
- void *virt_base = (void *)PAGE_OFFSET;
-
- info->var.xres_virtual = 640;
- info->var.yres_virtual = 240;
- info->var.bits_per_pixel = 4;
- info->var.activate = FB_ACTIVATE_NOW;
- info->var.height = -1;
- info->var.width = -1;
- info->var.pixclock = 93006; /* 10.752MHz pixel clock */
-
- /*
- * If the LCD controller is already running, decode the values
- * in LCDCON to xres/yres/bpp/pixclock/acprescale
- */
- syscon = clps_readl(SYSCON1);
- if (syscon & SYSCON1_LCDEN) {
- lcdcon = clps_readl(LCDCON);
-
- /*
- * Decode GSMD and GSEN bits to bits per pixel
- */
- switch (lcdcon & (LCDCON_GSMD | LCDCON_GSEN)) {
- case LCDCON_GSMD | LCDCON_GSEN:
- info->var.bits_per_pixel = 4;
- break;
-
- case LCDCON_GSEN:
- info->var.bits_per_pixel = 2;
- break;
-
- default:
- info->var.bits_per_pixel = 1;
- break;
- }
-
- /*
- * Decode xres/yres
- */
- info->var.xres_virtual = (((lcdcon >> 13) & 0x3f) + 1) * 16;
- info->var.yres_virtual = (((lcdcon & 0x1fff) + 1) * 128) /
- (info->var.xres_virtual *
- info->var.bits_per_pixel);
-
- /*
- * Calculate pixclock
- */
- info->var.pixclock = (((lcdcon >> 19) & 0x3f) + 1) * 244140 / 9;
-
- /*
- * Grab AC prescale
- */
- lcd_ac_prescale = (lcdcon >> 25) & 0x1f;
- }
-
- info->var.xres = info->var.xres_virtual;
- info->var.yres = info->var.yres_virtual;
- info->var.grayscale = info->var.bits_per_pixel > 1;
-
- size = info->var.xres * info->var.yres * info->var.bits_per_pixel / 8;
-
- /*
- * Might be worth checking to see if we can use the on-board
- * RAM if size here...
- * CLPS7110 - no on-board SRAM
- * EP7212 - 38400 bytes
- */
- if (size <= 38400) {
- printk(KERN_INFO "CLPS711xFB: could use on-board SRAM?\n");
- }
-
- if ((syscon & SYSCON1_LCDEN) = 0) {
- /*
- * The display isn't running. Ensure that
- * the display memory is empty.
- */
- memset(virt_base, 0, size);
- }
-
- info->screen_base = virt_base;
- info->fix.smem_start = phys_base;
- info->fix.smem_len = PAGE_ALIGN(size);
- info->fix.type = FB_TYPE_PACKED_PIXELS;
-}
-
-static int clps711x_fb_probe(struct platform_device *pdev)
-{
- int err = -ENOMEM;
-
- if (fb_get_options("clps711xfb", NULL))
- return -ENODEV;
-
- cfb = kzalloc(sizeof(*cfb), GFP_KERNEL);
- if (!cfb)
- goto out;
-
- strcpy(cfb->fix.id, "clps711x");
-
- cfb->fbops = &clps7111fb_ops;
- cfb->flags = FBINFO_DEFAULT;
-
- clps711x_guess_lcd_params(cfb);
-
- fb_alloc_cmap(&cfb->cmap, CMAP_MAX_SIZE, 0);
-
- err = register_framebuffer(cfb);
-
-out: return err;
-}
-
-static int clps711x_fb_remove(struct platform_device *pdev)
-{
- unregister_framebuffer(cfb);
- kfree(cfb);
-
- return 0;
-}
-
-static struct platform_driver clps711x_fb_driver = {
- .driver = {
- .name = "video-clps711x",
- .owner = THIS_MODULE,
- },
- .probe = clps711x_fb_probe,
- .remove = clps711x_fb_remove,
-};
-module_platform_driver(clps711x_fb_driver);
-
-MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
-MODULE_DESCRIPTION("CLPS711X framebuffer driver");
-MODULE_LICENSE("GPL");
--
1.8.3.2
^ permalink raw reply related
* [PATCH 3/3] video: clps711x: Add bindings documentation for CLPS711X framebuffer
From: Alexander Shiyan @ 2014-03-20 16:26 UTC (permalink / raw)
To: linux-fbdev-u79uwXL29TY76Z2rM5mHXA
Cc: Jean-Christophe Plagniol-Villard, Tomi Valkeinen, Russell King,
Olof Johansson, Arnd Bergmann, devicetree-u79uwXL29TY76Z2rM5mHXA,
Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
Grant Likely, Alexander Shiyan
Add OF document for Cirrus Logic CLPS711X framebuffer driver.
Signed-off-by: Alexander Shiyan <shc_work@mail.ru>
---
.../bindings/video/cirrus,clps711x-fb.txt | 48 ++++++++++++++++++++++
1 file changed, 48 insertions(+)
create mode 100644 Documentation/devicetree/bindings/video/cirrus,clps711x-fb.txt
diff --git a/Documentation/devicetree/bindings/video/cirrus,clps711x-fb.txt b/Documentation/devicetree/bindings/video/cirrus,clps711x-fb.txt
new file mode 100644
index 0000000..9d59ad3
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/cirrus,clps711x-fb.txt
@@ -0,0 +1,48 @@
+* Currus Logic CLPS711X Framebuffer
+
+Required properties:
+- compatible: Shall contain "cirrus,clps711x-fb".
+- reg: Physical base address and length of the controller's registers +
+ location and size of the framebuffer memory.
+- clocks: phandle + clock specifier pair of the FB reference clock.
+
+Required nodes:
+- display: Phandle to a display node as described in display-timing.txt.
+ Additionally, the display node has to define properties:
+ - bits-per-pixel: Bits per pixel.
+ - ac-prescale: LCD AC bias frequency. This frequency is the required
+ AC bias frequency for a given manufacturer's LCD plate.
+ - cmap-invert: Invert the color levels (Optional).
+
+Optional properties:
+- lcd-supply: Regulator for LCD supply voltage.
+
+Example:
+ fb: fb@800002c0 {
+ compatible = "cirrus,ep7312-fb", "cirrus,clps711x-fb";
+ reg = <0x800002c0 0xd44>, <0x60000000 0xc000>;
+ clocks = <&clks 2>;
+ lcd-supply = <®5v0>;
+ display = <&display>;
+ };
+
+ display: display {
+ model = "320x240x4";
+ native-mode = <&timing0>;
+ bits-per-pixel = <4>;
+ ac-prescale = <17>;
+
+ display-timings {
+ timing0: 320x240 {
+ hactive = <320>;
+ hback-porch = <0>;
+ hfront-porch = <0>;
+ hsync-len = <0>;
+ vactive = <240>;
+ vback-porch = <0>;
+ vfront-porch = <0>;
+ vsync-len = <0>;
+ clock-frequency = <6500000>;
+ };
+ };
+ };
--
1.8.3.2
^ permalink raw reply related
* Re: [PATCH 14/16] backlight: atmel-pwm-bl: remove obsolete driver
From: Jingoo Han @ 2014-03-21 0:51 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20140319142231.GF20872@samfundet.no>
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:
> > 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 <alexandre.belloni@free-electrons.com>
>
> Acked-by: Hans-Christian Egtvedt <egtvedt@samfundet.no>
Acked-by: Jingoo Han <jg1.han@samsung.com>
Best regards,
Jingoo Han
>
> > ---
> > 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
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox