Merge tag 'pwm/for-3.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm

Pull pwm changes from Thierry Reding:
"Mostly bug fixes and clean up. There is a new driver, which is
actually moving a custom PWM driver from drivers/misc.

The majority of the patches are enhancements to the device tree
support in the pwm-backlight driver. Backlights can now additionally
be powered using a regulator and enabled using a GPIO in addition to
just the PWM input"

* tag 'pwm/for-3.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm: (30 commits)
Documentation/pwm: Update supported SoC name for pwm-samsung
pwm: samsung: Fix kernel warning while unexporting a channel
MAINTAINERS: Move PWM subsystem tree to kernel.org
Documentation/pwm: Fix trivial typos
pwm-backlight: Remove unused variable
pwm_backlight: avoid short blank screen while doing hibernation
pwm-backlight: Fix brightness adjustment
pwm: add ep93xx PWM support
pwm-backlight: Allow for non-increasing brightness levels
pwm-backlight: Add power supply support
pwm-backlight: Use new enable_gpio field
unicore32: Initialize PWM backlight enable_gpio field
ARM: shmobile: Initialize PWM backlight enable_gpio field
ARM: SAMSUNG: Initialize PWM backlight enable_gpio field
ARM: pxa: Initialize PWM backlight enable_gpio field
ARM: OMAP: Initialize PWM backlight enable_gpio field
pwm-backlight: Add optional enable GPIO
pwm-backlight: Track enable state
pwm-backlight: Refactor backlight power on/off
pwm-backlight: Improve readability
...

+433 -392
+1 -1
Documentation/devicetree/bindings/pwm/pwm-samsung.txt
··· 15 15 samsung,s5pc100-pwm - for 32-bit timers present on S5PC100, S5PV210, 16 16 Exynos4210 rev0 SoCs 17 17 samsung,exynos4210-pwm - for 32-bit timers present on Exynos4210, 18 - Exynos4x12 and Exynos5250 SoCs 18 + Exynos4x12, Exynos5250 and Exynos5420 SoCs 19 19 - reg: base address and size of register area 20 20 - interrupts: list of timer interrupts (one interrupt per timer, starting at 21 21 timer 0)
+7
Documentation/devicetree/bindings/video/backlight/pwm-backlight.txt
··· 10 10 last value in the array represents a 100% duty cycle (brightest). 11 11 - default-brightness-level: the default brightness level (index into the 12 12 array defined by the "brightness-levels" property) 13 + - power-supply: regulator for supply voltage 13 14 14 15 Optional properties: 15 16 - pwm-names: a list of names for the PWM devices specified in the 16 17 "pwms" property (see PWM binding[0]) 18 + - enable-gpios: contains a single GPIO specifier for the GPIO which enables 19 + and disables the backlight (see GPIO binding[1]) 17 20 18 21 [0]: Documentation/devicetree/bindings/pwm/pwm.txt 22 + [1]: Documentation/devicetree/bindings/gpio/gpio.txt 19 23 20 24 Example: 21 25 ··· 29 25 30 26 brightness-levels = <0 4 8 16 32 64 128 255>; 31 27 default-brightness-level = <6>; 28 + 29 + power-supply = <&vdd_bl_reg>; 30 + enable-gpios = <&gpio 58 0>; 32 31 };
+2 -2
Documentation/pwm.txt
··· 39 39 device or a consumer name. pwm_put() is used to free the PWM device. Managed 40 40 variants of these functions, devm_pwm_get() and devm_pwm_put(), also exist. 41 41 42 - After being requested a PWM has to be configured using: 42 + After being requested, a PWM has to be configured using: 43 43 44 44 int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns); 45 45 ··· 94 94 A new PWM controller/chip can be added using pwmchip_add() and removed 95 95 again with pwmchip_remove(). pwmchip_add() takes a filled in struct 96 96 pwm_chip as argument which provides a description of the PWM chip, the 97 - number of PWM devices provider by the chip and the chip-specific 97 + number of PWM devices provided by the chip and the chip-specific 98 98 implementation of the supported PWM operations to the framework. 99 99 100 100 Locking
+1 -2
MAINTAINERS
··· 6785 6785 M: Thierry Reding <thierry.reding@gmail.com> 6786 6786 L: linux-pwm@vger.kernel.org 6787 6787 S: Maintained 6788 - W: http://gitorious.org/linux-pwm 6789 - T: git git://gitorious.org/linux-pwm/linux-pwm.git 6788 + T: git git://git.kernel.org/pub/scm/linux/kernel/git/thierry.reding/linux-pwm.git 6790 6789 F: Documentation/pwm.txt 6791 6790 F: Documentation/devicetree/bindings/pwm/ 6792 6791 F: include/linux/pwm.h
+1
arch/arm/mach-pxa/cm-x300.c
··· 310 310 .max_brightness = 100, 311 311 .dft_brightness = 100, 312 312 .pwm_period_ns = 10000, 313 + .enable_gpio = -1, 313 314 }; 314 315 315 316 static struct platform_device cm_x300_backlight_device = {
+1
arch/arm/mach-pxa/colibri-pxa270-income.c
··· 189 189 .max_brightness = 0x3ff, 190 190 .dft_brightness = 0x1ff, 191 191 .pwm_period_ns = 1000000, 192 + .enable_gpio = -1, 192 193 }; 193 194 194 195 static struct platform_device income_backlight = {
+1
arch/arm/mach-pxa/ezx.c
··· 54 54 .max_brightness = 1023, 55 55 .dft_brightness = 1023, 56 56 .pwm_period_ns = 78770, 57 + .enable_gpio = -1, 57 58 }; 58 59 59 60 static struct platform_device ezx_backlight_device = {
+1
arch/arm/mach-pxa/hx4700.c
··· 561 561 .max_brightness = 200, 562 562 .dft_brightness = 100, 563 563 .pwm_period_ns = 30923, 564 + .enable_gpio = -1, 564 565 }; 565 566 566 567 static struct platform_device backlight = {
+1
arch/arm/mach-pxa/lpd270.c
··· 269 269 .max_brightness = 1, 270 270 .dft_brightness = 1, 271 271 .pwm_period_ns = 78770, 272 + .enable_gpio = -1, 272 273 }; 273 274 274 275 static struct platform_device lpd270_backlight_device = {
+1
arch/arm/mach-pxa/magician.c
··· 378 378 .max_brightness = 272, 379 379 .dft_brightness = 100, 380 380 .pwm_period_ns = 30923, 381 + .enable_gpio = -1, 381 382 .init = magician_backlight_init, 382 383 .notify = magician_backlight_notify, 383 384 .exit = magician_backlight_exit,
+1
arch/arm/mach-pxa/mainstone.c
··· 338 338 .max_brightness = 1023, 339 339 .dft_brightness = 1023, 340 340 .pwm_period_ns = 78770, 341 + .enable_gpio = -1, 341 342 }; 342 343 343 344 static struct platform_device mainstone_backlight_device = {
+1
arch/arm/mach-pxa/mioa701.c
··· 186 186 .max_brightness = 100, 187 187 .dft_brightness = 50, 188 188 .pwm_period_ns = 4000 * 1024, /* Fl = 250kHz */ 189 + .enable_gpio = -1, 189 190 }; 190 191 191 192 /*
+1
arch/arm/mach-pxa/palm27x.c
··· 322 322 .max_brightness = 0xfe, 323 323 .dft_brightness = 0x7e, 324 324 .pwm_period_ns = 3500 * 1024, 325 + .enable_gpio = -1, 325 326 .init = palm27x_backlight_init, 326 327 .notify = palm27x_backlight_notify, 327 328 .exit = palm27x_backlight_exit,
+1 -34
arch/arm/mach-pxa/palmtc.c
··· 166 166 * Backlight 167 167 ******************************************************************************/ 168 168 #if defined(CONFIG_BACKLIGHT_PWM) || defined(CONFIG_BACKLIGHT_PWM_MODULE) 169 - static int palmtc_backlight_init(struct device *dev) 170 - { 171 - int ret; 172 - 173 - ret = gpio_request(GPIO_NR_PALMTC_BL_POWER, "BL POWER"); 174 - if (ret) 175 - goto err; 176 - ret = gpio_direction_output(GPIO_NR_PALMTC_BL_POWER, 1); 177 - if (ret) 178 - goto err2; 179 - 180 - return 0; 181 - 182 - err2: 183 - gpio_free(GPIO_NR_PALMTC_BL_POWER); 184 - err: 185 - return ret; 186 - } 187 - 188 - static int palmtc_backlight_notify(struct device *dev, int brightness) 189 - { 190 - /* backlight is on when GPIO16 AF0 is high */ 191 - gpio_set_value(GPIO_NR_PALMTC_BL_POWER, brightness); 192 - return brightness; 193 - } 194 - 195 - static void palmtc_backlight_exit(struct device *dev) 196 - { 197 - gpio_free(GPIO_NR_PALMTC_BL_POWER); 198 - } 199 - 200 169 static struct platform_pwm_backlight_data palmtc_backlight_data = { 201 170 .pwm_id = 1, 202 171 .max_brightness = PALMTC_MAX_INTENSITY, 203 172 .dft_brightness = PALMTC_MAX_INTENSITY, 204 173 .pwm_period_ns = PALMTC_PERIOD_NS, 205 - .init = palmtc_backlight_init, 206 - .notify = palmtc_backlight_notify, 207 - .exit = palmtc_backlight_exit, 174 + .enable_gpio = GPIO_NR_PALMTC_BL_POWER, 208 175 }; 209 176 210 177 static struct platform_device palmtc_backlight = {
+1
arch/arm/mach-pxa/palmte2.c
··· 165 165 .max_brightness = PALMTE2_MAX_INTENSITY, 166 166 .dft_brightness = PALMTE2_MAX_INTENSITY, 167 167 .pwm_period_ns = PALMTE2_PERIOD_NS, 168 + .enable_gpio = -1, 168 169 .init = palmte2_backlight_init, 169 170 .notify = palmte2_backlight_notify, 170 171 .exit = palmte2_backlight_exit,
+1
arch/arm/mach-pxa/pcm990-baseboard.c
··· 153 153 .max_brightness = 1023, 154 154 .dft_brightness = 1023, 155 155 .pwm_period_ns = 78770, 156 + .enable_gpio = -1, 156 157 }; 157 158 158 159 static struct platform_device pcm990_backlight_device = {
+1
arch/arm/mach-pxa/raumfeld.c
··· 539 539 .dft_brightness = 100, 540 540 /* 10000 ns = 10 ms ^= 100 kHz */ 541 541 .pwm_period_ns = 10000, 542 + .enable_gpio = -1, 542 543 }; 543 544 544 545 static struct platform_device raumfeld_pwm_backlight_device = {
+2
arch/arm/mach-pxa/tavorevb.c
··· 175 175 .max_brightness = 100, 176 176 .dft_brightness = 100, 177 177 .pwm_period_ns = 100000, 178 + .enable_gpio = -1, 178 179 }, 179 180 [1] = { 180 181 /* secondary backlight */ ··· 183 182 .max_brightness = 100, 184 183 .dft_brightness = 100, 185 184 .pwm_period_ns = 100000, 185 + .enable_gpio = -1, 186 186 }, 187 187 }; 188 188
+1
arch/arm/mach-pxa/viper.c
··· 401 401 .max_brightness = 100, 402 402 .dft_brightness = 100, 403 403 .pwm_period_ns = 1000000, 404 + .enable_gpio = -1, 404 405 .init = viper_backlight_init, 405 406 .notify = viper_backlight_notify, 406 407 .exit = viper_backlight_exit,
+2
arch/arm/mach-pxa/z2.c
··· 206 206 .max_brightness = 1023, 207 207 .dft_brightness = 0, 208 208 .pwm_period_ns = 1260320, 209 + .enable_gpio = -1, 209 210 }, 210 211 [1] = { 211 212 /* LCD Backlight */ ··· 214 213 .max_brightness = 1023, 215 214 .dft_brightness = 512, 216 215 .pwm_period_ns = 1260320, 216 + .enable_gpio = -1, 217 217 }, 218 218 }; 219 219
+1
arch/arm/mach-pxa/zylonite.c
··· 125 125 .max_brightness = 100, 126 126 .dft_brightness = 100, 127 127 .pwm_period_ns = 10000, 128 + .enable_gpio = -1, 128 129 }; 129 130 130 131 static struct platform_device zylonite_backlight_device = {
+1
arch/arm/mach-s3c24xx/mach-h1940.c
··· 504 504 .dft_brightness = 50, 505 505 /* tcnt = 0x31 */ 506 506 .pwm_period_ns = 36296, 507 + .enable_gpio = -1, 507 508 .init = h1940_backlight_init, 508 509 .notify = h1940_backlight_notify, 509 510 .exit = h1940_backlight_exit,
+1
arch/arm/mach-s3c24xx/mach-rx1950.c
··· 522 522 .max_brightness = 24, 523 523 .dft_brightness = 4, 524 524 .pwm_period_ns = 48000, 525 + .enable_gpio = -1, 525 526 .init = rx1950_backlight_init, 526 527 .notify = rx1950_backlight_notify, 527 528 .exit = rx1950_backlight_exit,
+1
arch/arm/mach-s3c64xx/mach-crag6410.c
··· 114 114 .max_brightness = 1000, 115 115 .dft_brightness = 600, 116 116 .pwm_period_ns = 100000, /* about 1kHz */ 117 + .enable_gpio = -1, 117 118 }; 118 119 119 120 static struct platform_device crag6410_backlight_device = {
+1
arch/arm/mach-s3c64xx/mach-hmt.c
··· 114 114 .max_brightness = 100 * 256, 115 115 .dft_brightness = 40 * 256, 116 116 .pwm_period_ns = 1000000000 / (100 * 256 * 20), 117 + .enable_gpio = -1, 117 118 .init = hmt_bl_init, 118 119 .notify = hmt_bl_notify, 119 120 .exit = hmt_bl_exit,
+1
arch/arm/mach-s3c64xx/mach-smartq.c
··· 151 151 .max_brightness = 1000, 152 152 .dft_brightness = 600, 153 153 .pwm_period_ns = 1000000000 / (1000 * 20), 154 + .enable_gpio = -1, 154 155 .init = smartq_bl_init, 155 156 }; 156 157
+1
arch/arm/mach-s3c64xx/mach-smdk6410.c
··· 625 625 626 626 static struct platform_pwm_backlight_data smdk6410_bl_data = { 627 627 .pwm_id = 1, 628 + .enable_gpio = -1, 628 629 }; 629 630 630 631 static struct s3c_hsotg_plat smdk6410_hsotg_pdata;
+1
arch/arm/mach-s5p64x0/mach-smdk6440.c
··· 223 223 224 224 static struct platform_pwm_backlight_data smdk6440_bl_data = { 225 225 .pwm_id = 1, 226 + .enable_gpio = -1, 226 227 }; 227 228 228 229 static void __init smdk6440_map_io(void)
+1
arch/arm/mach-s5p64x0/mach-smdk6450.c
··· 242 242 243 243 static struct platform_pwm_backlight_data smdk6450_bl_data = { 244 244 .pwm_id = 1, 245 + .enable_gpio = -1, 245 246 }; 246 247 247 248 static void __init smdk6450_map_io(void)
+1
arch/arm/mach-s5pc100/mach-smdkc100.c
··· 216 216 217 217 static struct platform_pwm_backlight_data smdkc100_bl_data = { 218 218 .pwm_id = 0, 219 + .enable_gpio = -1, 219 220 }; 220 221 221 222 static void __init smdkc100_map_io(void)
+1
arch/arm/mach-s5pv210/mach-smdkv210.c
··· 279 279 static struct platform_pwm_backlight_data smdkv210_bl_data = { 280 280 .pwm_id = 3, 281 281 .pwm_period_ns = 1000, 282 + .enable_gpio = -1, 282 283 }; 283 284 284 285 static void __init smdkv210_map_io(void)
+1
arch/arm/mach-shmobile/board-armadillo800eva.c
··· 423 423 .max_brightness = 255, 424 424 .dft_brightness = 255, 425 425 .pwm_period_ns = 33333, /* 30kHz */ 426 + .enable_gpio = -1, 426 427 }; 427 428 428 429 static struct platform_device pwm_backlight_device = {
+5
arch/arm/plat-samsung/dev-backlight.c
··· 70 70 .max_brightness = 255, 71 71 .dft_brightness = 255, 72 72 .pwm_period_ns = 78770, 73 + .enable_gpio = -1, 73 74 .init = samsung_bl_init, 74 75 .exit = samsung_bl_exit, 75 76 }, ··· 122 121 samsung_bl_data->lth_brightness = bl_data->lth_brightness; 123 122 if (bl_data->pwm_period_ns) 124 123 samsung_bl_data->pwm_period_ns = bl_data->pwm_period_ns; 124 + if (bl_data->enable_gpio >= 0) 125 + samsung_bl_data->enable_gpio = bl_data->enable_gpio; 126 + if (bl_data->enable_gpio_flags) 127 + samsung_bl_data->enable_gpio_flags = bl_data->enable_gpio_flags; 125 128 if (bl_data->init) 126 129 samsung_bl_data->init = bl_data->init; 127 130 if (bl_data->notify)
+1
arch/unicore32/kernel/puv3-nb0916.c
··· 54 54 .max_brightness = 100, 55 55 .dft_brightness = 100, 56 56 .pwm_period_ns = 70 * 1024, 57 + .enable_gpio = -1, 57 58 }; 58 59 59 60 static struct gpio_keys_button nb0916_gpio_keys[] = {
-13
drivers/misc/Kconfig
··· 381 381 This driver provides support for the Honeywell HMC6352 compass, 382 382 providing configuration and heading data via sysfs. 383 383 384 - config EP93XX_PWM 385 - tristate "EP93xx PWM support" 386 - depends on ARCH_EP93XX 387 - help 388 - This option enables device driver support for the PWM channels 389 - on the Cirrus EP93xx processors. The EP9307 chip only has one 390 - PWM channel all the others have two, the second channel is an 391 - alternate function of the EGPIO14 pin. A sysfs interface is 392 - provided to control the PWM channels. 393 - 394 - To compile this driver as a module, choose M here: the module will 395 - be called ep93xx_pwm. 396 - 397 384 config DS1682 398 385 tristate "Dallas DS1682 Total Elapsed Time Recorder with Alarm" 399 386 depends on I2C
-1
drivers/misc/Makefile
··· 33 33 obj-$(CONFIG_ISL29003) += isl29003.o 34 34 obj-$(CONFIG_ISL29020) += isl29020.o 35 35 obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o 36 - obj-$(CONFIG_EP93XX_PWM) += ep93xx_pwm.o 37 36 obj-$(CONFIG_DS1682) += ds1682.o 38 37 obj-$(CONFIG_TI_DAC7512) += ti_dac7512.o 39 38 obj-$(CONFIG_C2PORT) += c2port/
-286
drivers/misc/ep93xx_pwm.c
··· 1 - /* 2 - * Simple PWM driver for EP93XX 3 - * 4 - * (c) Copyright 2009 Matthieu Crapet <mcrapet@gmail.com> 5 - * (c) Copyright 2009 H Hartley Sweeten <hsweeten@visionengravers.com> 6 - * 7 - * This program is free software; you can redistribute it and/or 8 - * modify it under the terms of the GNU General Public License 9 - * as published by the Free Software Foundation; either version 10 - * 2 of the License, or (at your option) any later version. 11 - * 12 - * EP9307 has only one channel: 13 - * - PWMOUT 14 - * 15 - * EP9301/02/12/15 have two channels: 16 - * - PWMOUT 17 - * - PWMOUT1 (alternate function for EGPIO14) 18 - */ 19 - 20 - #include <linux/module.h> 21 - #include <linux/platform_device.h> 22 - #include <linux/slab.h> 23 - #include <linux/clk.h> 24 - #include <linux/err.h> 25 - #include <linux/io.h> 26 - 27 - #include <mach/platform.h> 28 - 29 - #define EP93XX_PWMx_TERM_COUNT 0x00 30 - #define EP93XX_PWMx_DUTY_CYCLE 0x04 31 - #define EP93XX_PWMx_ENABLE 0x08 32 - #define EP93XX_PWMx_INVERT 0x0C 33 - 34 - #define EP93XX_PWM_MAX_COUNT 0xFFFF 35 - 36 - struct ep93xx_pwm { 37 - void __iomem *mmio_base; 38 - struct clk *clk; 39 - u32 duty_percent; 40 - }; 41 - 42 - /* 43 - * /sys/devices/platform/ep93xx-pwm.N 44 - * /min_freq read-only minimum pwm output frequency 45 - * /max_req read-only maximum pwm output frequency 46 - * /freq read-write pwm output frequency (0 = disable output) 47 - * /duty_percent read-write pwm duty cycle percent (1..99) 48 - * /invert read-write invert pwm output 49 - */ 50 - 51 - static ssize_t ep93xx_pwm_get_min_freq(struct device *dev, 52 - struct device_attribute *attr, char *buf) 53 - { 54 - struct platform_device *pdev = to_platform_device(dev); 55 - struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); 56 - unsigned long rate = clk_get_rate(pwm->clk); 57 - 58 - return sprintf(buf, "%ld\n", rate / (EP93XX_PWM_MAX_COUNT + 1)); 59 - } 60 - 61 - static ssize_t ep93xx_pwm_get_max_freq(struct device *dev, 62 - struct device_attribute *attr, char *buf) 63 - { 64 - struct platform_device *pdev = to_platform_device(dev); 65 - struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); 66 - unsigned long rate = clk_get_rate(pwm->clk); 67 - 68 - return sprintf(buf, "%ld\n", rate / 2); 69 - } 70 - 71 - static ssize_t ep93xx_pwm_get_freq(struct device *dev, 72 - struct device_attribute *attr, char *buf) 73 - { 74 - struct platform_device *pdev = to_platform_device(dev); 75 - struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); 76 - 77 - if (readl(pwm->mmio_base + EP93XX_PWMx_ENABLE) & 0x1) { 78 - unsigned long rate = clk_get_rate(pwm->clk); 79 - u16 term = readl(pwm->mmio_base + EP93XX_PWMx_TERM_COUNT); 80 - 81 - return sprintf(buf, "%ld\n", rate / (term + 1)); 82 - } else { 83 - return sprintf(buf, "disabled\n"); 84 - } 85 - } 86 - 87 - static ssize_t ep93xx_pwm_set_freq(struct device *dev, 88 - struct device_attribute *attr, const char *buf, size_t count) 89 - { 90 - struct platform_device *pdev = to_platform_device(dev); 91 - struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); 92 - long val; 93 - int err; 94 - 95 - err = kstrtol(buf, 10, &val); 96 - if (err) 97 - return -EINVAL; 98 - 99 - if (val == 0) { 100 - writel(0x0, pwm->mmio_base + EP93XX_PWMx_ENABLE); 101 - } else if (val <= (clk_get_rate(pwm->clk) / 2)) { 102 - u32 term, duty; 103 - 104 - val = (clk_get_rate(pwm->clk) / val) - 1; 105 - if (val > EP93XX_PWM_MAX_COUNT) 106 - val = EP93XX_PWM_MAX_COUNT; 107 - if (val < 1) 108 - val = 1; 109 - 110 - term = readl(pwm->mmio_base + EP93XX_PWMx_TERM_COUNT); 111 - duty = ((val + 1) * pwm->duty_percent / 100) - 1; 112 - 113 - /* If pwm is running, order is important */ 114 - if (val > term) { 115 - writel(val, pwm->mmio_base + EP93XX_PWMx_TERM_COUNT); 116 - writel(duty, pwm->mmio_base + EP93XX_PWMx_DUTY_CYCLE); 117 - } else { 118 - writel(duty, pwm->mmio_base + EP93XX_PWMx_DUTY_CYCLE); 119 - writel(val, pwm->mmio_base + EP93XX_PWMx_TERM_COUNT); 120 - } 121 - 122 - if (!readl(pwm->mmio_base + EP93XX_PWMx_ENABLE) & 0x1) 123 - writel(0x1, pwm->mmio_base + EP93XX_PWMx_ENABLE); 124 - } else { 125 - return -EINVAL; 126 - } 127 - 128 - return count; 129 - } 130 - 131 - static ssize_t ep93xx_pwm_get_duty_percent(struct device *dev, 132 - struct device_attribute *attr, char *buf) 133 - { 134 - struct platform_device *pdev = to_platform_device(dev); 135 - struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); 136 - 137 - return sprintf(buf, "%d\n", pwm->duty_percent); 138 - } 139 - 140 - static ssize_t ep93xx_pwm_set_duty_percent(struct device *dev, 141 - struct device_attribute *attr, const char *buf, size_t count) 142 - { 143 - struct platform_device *pdev = to_platform_device(dev); 144 - struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); 145 - long val; 146 - int err; 147 - 148 - err = kstrtol(buf, 10, &val); 149 - if (err) 150 - return -EINVAL; 151 - 152 - if (val > 0 && val < 100) { 153 - u32 term = readl(pwm->mmio_base + EP93XX_PWMx_TERM_COUNT); 154 - u32 duty = ((term + 1) * val / 100) - 1; 155 - 156 - writel(duty, pwm->mmio_base + EP93XX_PWMx_DUTY_CYCLE); 157 - pwm->duty_percent = val; 158 - return count; 159 - } 160 - 161 - return -EINVAL; 162 - } 163 - 164 - static ssize_t ep93xx_pwm_get_invert(struct device *dev, 165 - struct device_attribute *attr, char *buf) 166 - { 167 - struct platform_device *pdev = to_platform_device(dev); 168 - struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); 169 - int inverted = readl(pwm->mmio_base + EP93XX_PWMx_INVERT) & 0x1; 170 - 171 - return sprintf(buf, "%d\n", inverted); 172 - } 173 - 174 - static ssize_t ep93xx_pwm_set_invert(struct device *dev, 175 - struct device_attribute *attr, const char *buf, size_t count) 176 - { 177 - struct platform_device *pdev = to_platform_device(dev); 178 - struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); 179 - long val; 180 - int err; 181 - 182 - err = kstrtol(buf, 10, &val); 183 - if (err) 184 - return -EINVAL; 185 - 186 - if (val == 0) 187 - writel(0x0, pwm->mmio_base + EP93XX_PWMx_INVERT); 188 - else if (val == 1) 189 - writel(0x1, pwm->mmio_base + EP93XX_PWMx_INVERT); 190 - else 191 - return -EINVAL; 192 - 193 - return count; 194 - } 195 - 196 - static DEVICE_ATTR(min_freq, S_IRUGO, ep93xx_pwm_get_min_freq, NULL); 197 - static DEVICE_ATTR(max_freq, S_IRUGO, ep93xx_pwm_get_max_freq, NULL); 198 - static DEVICE_ATTR(freq, S_IWUSR | S_IRUGO, 199 - ep93xx_pwm_get_freq, ep93xx_pwm_set_freq); 200 - static DEVICE_ATTR(duty_percent, S_IWUSR | S_IRUGO, 201 - ep93xx_pwm_get_duty_percent, ep93xx_pwm_set_duty_percent); 202 - static DEVICE_ATTR(invert, S_IWUSR | S_IRUGO, 203 - ep93xx_pwm_get_invert, ep93xx_pwm_set_invert); 204 - 205 - static struct attribute *ep93xx_pwm_attrs[] = { 206 - &dev_attr_min_freq.attr, 207 - &dev_attr_max_freq.attr, 208 - &dev_attr_freq.attr, 209 - &dev_attr_duty_percent.attr, 210 - &dev_attr_invert.attr, 211 - NULL 212 - }; 213 - 214 - static const struct attribute_group ep93xx_pwm_sysfs_files = { 215 - .attrs = ep93xx_pwm_attrs, 216 - }; 217 - 218 - static int ep93xx_pwm_probe(struct platform_device *pdev) 219 - { 220 - struct ep93xx_pwm *pwm; 221 - struct resource *res; 222 - int ret; 223 - 224 - pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL); 225 - if (!pwm) 226 - return -ENOMEM; 227 - 228 - pwm->clk = devm_clk_get(&pdev->dev, "pwm_clk"); 229 - if (IS_ERR(pwm->clk)) 230 - return PTR_ERR(pwm->clk); 231 - 232 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 233 - pwm->mmio_base = devm_ioremap_resource(&pdev->dev, res); 234 - if (IS_ERR(pwm->mmio_base)) 235 - return PTR_ERR(pwm->mmio_base); 236 - 237 - ret = ep93xx_pwm_acquire_gpio(pdev); 238 - if (ret) 239 - return ret; 240 - 241 - ret = sysfs_create_group(&pdev->dev.kobj, &ep93xx_pwm_sysfs_files); 242 - if (ret) { 243 - ep93xx_pwm_release_gpio(pdev); 244 - return ret; 245 - } 246 - 247 - pwm->duty_percent = 50; 248 - 249 - /* disable pwm at startup. Avoids zero value. */ 250 - writel(0x0, pwm->mmio_base + EP93XX_PWMx_ENABLE); 251 - writel(EP93XX_PWM_MAX_COUNT, pwm->mmio_base + EP93XX_PWMx_TERM_COUNT); 252 - writel(EP93XX_PWM_MAX_COUNT/2, pwm->mmio_base + EP93XX_PWMx_DUTY_CYCLE); 253 - 254 - clk_enable(pwm->clk); 255 - 256 - platform_set_drvdata(pdev, pwm); 257 - return 0; 258 - } 259 - 260 - static int ep93xx_pwm_remove(struct platform_device *pdev) 261 - { 262 - struct ep93xx_pwm *pwm = platform_get_drvdata(pdev); 263 - 264 - writel(0x0, pwm->mmio_base + EP93XX_PWMx_ENABLE); 265 - clk_disable(pwm->clk); 266 - sysfs_remove_group(&pdev->dev.kobj, &ep93xx_pwm_sysfs_files); 267 - ep93xx_pwm_release_gpio(pdev); 268 - 269 - return 0; 270 - } 271 - 272 - static struct platform_driver ep93xx_pwm_driver = { 273 - .driver = { 274 - .name = "ep93xx-pwm", 275 - .owner = THIS_MODULE, 276 - }, 277 - .probe = ep93xx_pwm_probe, 278 - .remove = ep93xx_pwm_remove, 279 - }; 280 - module_platform_driver(ep93xx_pwm_driver); 281 - 282 - MODULE_AUTHOR("Matthieu Crapet <mcrapet@gmail.com>, " 283 - "H Hartley Sweeten <hsweeten@visionengravers.com>"); 284 - MODULE_DESCRIPTION("EP93xx PWM driver"); 285 - MODULE_LICENSE("GPL"); 286 - MODULE_ALIAS("platform:ep93xx-pwm");
+9
drivers/pwm/Kconfig
··· 62 62 To compile this driver as a module, choose M here: the module 63 63 will be called pwm-bfin. 64 64 65 + config PWM_EP93XX 66 + tristate "Cirrus Logic EP93xx PWM support" 67 + depends on ARCH_EP93XX 68 + help 69 + Generic PWM framework driver for Cirrus Logic EP93xx. 70 + 71 + To compile this driver as a module, choose M here: the module 72 + will be called pwm-ep93xx. 73 + 65 74 config PWM_IMX 66 75 tristate "i.MX PWM support" 67 76 depends on ARCH_MXC
+1
drivers/pwm/Makefile
··· 3 3 obj-$(CONFIG_PWM_AB8500) += pwm-ab8500.o 4 4 obj-$(CONFIG_PWM_ATMEL_TCB) += pwm-atmel-tcb.o 5 5 obj-$(CONFIG_PWM_BFIN) += pwm-bfin.o 6 + obj-$(CONFIG_PWM_EP93XX) += pwm-ep93xx.o 6 7 obj-$(CONFIG_PWM_IMX) += pwm-imx.o 7 8 obj-$(CONFIG_PWM_JZ4740) += pwm-jz4740.o 8 9 obj-$(CONFIG_PWM_LPC32XX) += pwm-lpc32xx.o
+3 -1
drivers/pwm/pwm-atmel-tcb.c
··· 249 249 } 250 250 } 251 251 252 + cmr |= (tcbpwm->div & ATMEL_TC_TCCLKS); 253 + 252 254 __raw_writel(cmr, regs + ATMEL_TC_REG(group, CMR)); 253 255 254 256 if (index == 0) ··· 307 305 i = slowclk; 308 306 rate = 32768; 309 307 min = div_u64(NSEC_PER_SEC, rate); 310 - max = min << 16; 308 + max = min << tc->tcb_config->counter_width; 311 309 312 310 /* If period is too big return ERANGE error */ 313 311 if (max < period_ns)
+230
drivers/pwm/pwm-ep93xx.c
··· 1 + /* 2 + * PWM framework driver for Cirrus Logic EP93xx 3 + * 4 + * Copyright (c) 2009 Matthieu Crapet <mcrapet@gmail.com> 5 + * Copyright (c) 2009, 2013 H Hartley Sweeten <hsweeten@visionengravers.com> 6 + * 7 + * EP9301/02 have only one channel: 8 + * platform device ep93xx-pwm.1 - PWMOUT1 (EGPIO14) 9 + * 10 + * EP9307 has only one channel: 11 + * platform device ep93xx-pwm.0 - PWMOUT 12 + * 13 + * EP9312/15 have two channels: 14 + * platform device ep93xx-pwm.0 - PWMOUT 15 + * platform device ep93xx-pwm.1 - PWMOUT1 (EGPIO14) 16 + * 17 + * This program is free software; you can redistribute it and/or 18 + * modify it under the terms of the GNU General Public License 19 + * as published by the Free Software Foundation; either version 20 + * 2 of the License, or (at your option) any later version. 21 + * 22 + * This program is distributed in the hope that it will be useful, 23 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 24 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25 + * GNU General Public License for more details. 26 + */ 27 + 28 + #include <linux/module.h> 29 + #include <linux/platform_device.h> 30 + #include <linux/slab.h> 31 + #include <linux/clk.h> 32 + #include <linux/err.h> 33 + #include <linux/io.h> 34 + #include <linux/pwm.h> 35 + 36 + #include <asm/div64.h> 37 + 38 + #include <mach/platform.h> /* for ep93xx_pwm_{acquire,release}_gpio() */ 39 + 40 + #define EP93XX_PWMx_TERM_COUNT 0x00 41 + #define EP93XX_PWMx_DUTY_CYCLE 0x04 42 + #define EP93XX_PWMx_ENABLE 0x08 43 + #define EP93XX_PWMx_INVERT 0x0c 44 + 45 + struct ep93xx_pwm { 46 + void __iomem *base; 47 + struct clk *clk; 48 + struct pwm_chip chip; 49 + }; 50 + 51 + static inline struct ep93xx_pwm *to_ep93xx_pwm(struct pwm_chip *chip) 52 + { 53 + return container_of(chip, struct ep93xx_pwm, chip); 54 + } 55 + 56 + static int ep93xx_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) 57 + { 58 + struct platform_device *pdev = to_platform_device(chip->dev); 59 + 60 + return ep93xx_pwm_acquire_gpio(pdev); 61 + } 62 + 63 + static void ep93xx_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) 64 + { 65 + struct platform_device *pdev = to_platform_device(chip->dev); 66 + 67 + ep93xx_pwm_release_gpio(pdev); 68 + } 69 + 70 + static int ep93xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, 71 + int duty_ns, int period_ns) 72 + { 73 + struct ep93xx_pwm *ep93xx_pwm = to_ep93xx_pwm(chip); 74 + void __iomem *base = ep93xx_pwm->base; 75 + unsigned long long c; 76 + unsigned long period_cycles; 77 + unsigned long duty_cycles; 78 + unsigned long term; 79 + int ret = 0; 80 + 81 + /* 82 + * The clock needs to be enabled to access the PWM registers. 83 + * Configuration can be changed at any time. 84 + */ 85 + if (!test_bit(PWMF_ENABLED, &pwm->flags)) { 86 + ret = clk_enable(ep93xx_pwm->clk); 87 + if (ret) 88 + return ret; 89 + } 90 + 91 + c = clk_get_rate(ep93xx_pwm->clk); 92 + c *= period_ns; 93 + do_div(c, 1000000000); 94 + period_cycles = c; 95 + 96 + c = period_cycles; 97 + c *= duty_ns; 98 + do_div(c, period_ns); 99 + duty_cycles = c; 100 + 101 + if (period_cycles < 0x10000 && duty_cycles < 0x10000) { 102 + term = readw(base + EP93XX_PWMx_TERM_COUNT); 103 + 104 + /* Order is important if PWM is running */ 105 + if (period_cycles > term) { 106 + writew(period_cycles, base + EP93XX_PWMx_TERM_COUNT); 107 + writew(duty_cycles, base + EP93XX_PWMx_DUTY_CYCLE); 108 + } else { 109 + writew(duty_cycles, base + EP93XX_PWMx_DUTY_CYCLE); 110 + writew(period_cycles, base + EP93XX_PWMx_TERM_COUNT); 111 + } 112 + } else { 113 + ret = -EINVAL; 114 + } 115 + 116 + if (!test_bit(PWMF_ENABLED, &pwm->flags)) 117 + clk_disable(ep93xx_pwm->clk); 118 + 119 + return ret; 120 + } 121 + 122 + static int ep93xx_pwm_polarity(struct pwm_chip *chip, struct pwm_device *pwm, 123 + enum pwm_polarity polarity) 124 + { 125 + struct ep93xx_pwm *ep93xx_pwm = to_ep93xx_pwm(chip); 126 + int ret; 127 + 128 + /* 129 + * The clock needs to be enabled to access the PWM registers. 130 + * Polarity can only be changed when the PWM is disabled. 131 + */ 132 + ret = clk_enable(ep93xx_pwm->clk); 133 + if (ret) 134 + return ret; 135 + 136 + if (polarity == PWM_POLARITY_INVERSED) 137 + writew(0x1, ep93xx_pwm->base + EP93XX_PWMx_INVERT); 138 + else 139 + writew(0x0, ep93xx_pwm->base + EP93XX_PWMx_INVERT); 140 + 141 + clk_disable(ep93xx_pwm->clk); 142 + 143 + return 0; 144 + } 145 + 146 + static int ep93xx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) 147 + { 148 + struct ep93xx_pwm *ep93xx_pwm = to_ep93xx_pwm(chip); 149 + int ret; 150 + 151 + ret = clk_enable(ep93xx_pwm->clk); 152 + if (ret) 153 + return ret; 154 + 155 + writew(0x1, ep93xx_pwm->base + EP93XX_PWMx_ENABLE); 156 + 157 + return 0; 158 + } 159 + 160 + static void ep93xx_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) 161 + { 162 + struct ep93xx_pwm *ep93xx_pwm = to_ep93xx_pwm(chip); 163 + 164 + writew(0x0, ep93xx_pwm->base + EP93XX_PWMx_ENABLE); 165 + clk_disable(ep93xx_pwm->clk); 166 + } 167 + 168 + static const struct pwm_ops ep93xx_pwm_ops = { 169 + .request = ep93xx_pwm_request, 170 + .free = ep93xx_pwm_free, 171 + .config = ep93xx_pwm_config, 172 + .set_polarity = ep93xx_pwm_polarity, 173 + .enable = ep93xx_pwm_enable, 174 + .disable = ep93xx_pwm_disable, 175 + .owner = THIS_MODULE, 176 + }; 177 + 178 + static int ep93xx_pwm_probe(struct platform_device *pdev) 179 + { 180 + struct ep93xx_pwm *ep93xx_pwm; 181 + struct resource *res; 182 + int ret; 183 + 184 + ep93xx_pwm = devm_kzalloc(&pdev->dev, sizeof(*ep93xx_pwm), GFP_KERNEL); 185 + if (!ep93xx_pwm) 186 + return -ENOMEM; 187 + 188 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 189 + ep93xx_pwm->base = devm_ioremap_resource(&pdev->dev, res); 190 + if (IS_ERR(ep93xx_pwm->base)) 191 + return PTR_ERR(ep93xx_pwm->base); 192 + 193 + ep93xx_pwm->clk = devm_clk_get(&pdev->dev, "pwm_clk"); 194 + if (IS_ERR(ep93xx_pwm->clk)) 195 + return PTR_ERR(ep93xx_pwm->clk); 196 + 197 + ep93xx_pwm->chip.dev = &pdev->dev; 198 + ep93xx_pwm->chip.ops = &ep93xx_pwm_ops; 199 + ep93xx_pwm->chip.base = -1; 200 + ep93xx_pwm->chip.npwm = 1; 201 + 202 + ret = pwmchip_add(&ep93xx_pwm->chip); 203 + if (ret < 0) 204 + return ret; 205 + 206 + platform_set_drvdata(pdev, ep93xx_pwm); 207 + return 0; 208 + } 209 + 210 + static int ep93xx_pwm_remove(struct platform_device *pdev) 211 + { 212 + struct ep93xx_pwm *ep93xx_pwm = platform_get_drvdata(pdev); 213 + 214 + return pwmchip_remove(&ep93xx_pwm->chip); 215 + } 216 + 217 + static struct platform_driver ep93xx_pwm_driver = { 218 + .driver = { 219 + .name = "ep93xx-pwm", 220 + }, 221 + .probe = ep93xx_pwm_probe, 222 + .remove = ep93xx_pwm_remove, 223 + }; 224 + module_platform_driver(ep93xx_pwm_driver); 225 + 226 + MODULE_DESCRIPTION("Cirrus Logic EP93xx PWM driver"); 227 + MODULE_AUTHOR("Matthieu Crapet <mcrapet@gmail.com>, " 228 + "H Hartley Sweeten <hsweeten@visionengravers.com>"); 229 + MODULE_ALIAS("platform:ep93xx-pwm"); 230 + MODULE_LICENSE("GPL");
+2 -1
drivers/pwm/pwm-imx.c
··· 16 16 #include <linux/clk.h> 17 17 #include <linux/io.h> 18 18 #include <linux/pwm.h> 19 + #include <linux/of.h> 19 20 #include <linux/of_device.h> 20 21 21 22 /* i.MX1 and i.MX21 share the same PWM function block: */ ··· 297 296 .driver = { 298 297 .name = "imx-pwm", 299 298 .owner = THIS_MODULE, 300 - .of_match_table = of_match_ptr(imx_pwm_dt_ids), 299 + .of_match_table = imx_pwm_dt_ids, 301 300 }, 302 301 .probe = imx_pwm_probe, 303 302 .remove = imx_pwm_remove,
+1 -1
drivers/pwm/pwm-lpc32xx.c
··· 169 169 .driver = { 170 170 .name = "lpc32xx-pwm", 171 171 .owner = THIS_MODULE, 172 - .of_match_table = of_match_ptr(lpc32xx_pwm_dt_ids), 172 + .of_match_table = lpc32xx_pwm_dt_ids, 173 173 }, 174 174 .probe = lpc32xx_pwm_probe, 175 175 .remove = lpc32xx_pwm_remove,
+1 -1
drivers/pwm/pwm-mxs.c
··· 189 189 .driver = { 190 190 .name = "mxs-pwm", 191 191 .owner = THIS_MODULE, 192 - .of_match_table = of_match_ptr(mxs_pwm_dt_ids), 192 + .of_match_table = mxs_pwm_dt_ids, 193 193 }, 194 194 .probe = mxs_pwm_probe, 195 195 .remove = mxs_pwm_remove,
+2 -1
drivers/pwm/pwm-samsung.c
··· 18 18 #include <linux/io.h> 19 19 #include <linux/kernel.h> 20 20 #include <linux/module.h> 21 + #include <linux/of.h> 21 22 #include <linux/platform_device.h> 22 23 #include <linux/pwm.h> 23 24 #include <linux/slab.h> ··· 225 224 226 225 static void pwm_samsung_free(struct pwm_chip *chip, struct pwm_device *pwm) 227 226 { 228 - pwm_set_chip_data(pwm, NULL); 229 227 devm_kfree(chip->dev, pwm_get_chip_data(pwm)); 228 + pwm_set_chip_data(pwm, NULL); 230 229 } 231 230 232 231 static int pwm_samsung_enable(struct pwm_chip *chip, struct pwm_device *pwm)
-6
drivers/pwm/pwm-tiecap.c
··· 26 26 #include <linux/pm_runtime.h> 27 27 #include <linux/pwm.h> 28 28 #include <linux/of_device.h> 29 - #include <linux/pinctrl/consumer.h> 30 29 31 30 #include "pwm-tipwmss.h" 32 31 ··· 207 208 struct clk *clk; 208 209 struct ecap_pwm_chip *pc; 209 210 u16 status; 210 - struct pinctrl *pinctrl; 211 - 212 - pinctrl = devm_pinctrl_get_select_default(&pdev->dev); 213 - if (IS_ERR(pinctrl)) 214 - dev_warn(&pdev->dev, "unable to select pin group\n"); 215 211 216 212 pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); 217 213 if (!pc) {
-6
drivers/pwm/pwm-tiehrpwm.c
··· 26 26 #include <linux/clk.h> 27 27 #include <linux/pm_runtime.h> 28 28 #include <linux/of_device.h> 29 - #include <linux/pinctrl/consumer.h> 30 29 31 30 #include "pwm-tipwmss.h" 32 31 ··· 438 439 struct clk *clk; 439 440 struct ehrpwm_pwm_chip *pc; 440 441 u16 status; 441 - struct pinctrl *pinctrl; 442 - 443 - pinctrl = devm_pinctrl_get_select_default(&pdev->dev); 444 - if (IS_ERR(pinctrl)) 445 - dev_warn(&pdev->dev, "unable to select pin group\n"); 446 442 447 443 pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); 448 444 if (!pc) {
+1
drivers/pwm/pwm-twl-led.c
··· 21 21 */ 22 22 23 23 #include <linux/module.h> 24 + #include <linux/of.h> 24 25 #include <linux/platform_device.h> 25 26 #include <linux/pwm.h> 26 27 #include <linux/i2c/twl.h>
+1
drivers/pwm/pwm-twl.c
··· 18 18 */ 19 19 20 20 #include <linux/module.h> 21 + #include <linux/of.h> 21 22 #include <linux/platform_device.h> 22 23 #include <linux/pwm.h> 23 24 #include <linux/i2c/twl.h>
+130 -36
drivers/video/backlight/pwm_bl.c
··· 10 10 * published by the Free Software Foundation. 11 11 */ 12 12 13 + #include <linux/gpio.h> 14 + #include <linux/of_gpio.h> 13 15 #include <linux/module.h> 14 16 #include <linux/kernel.h> 15 17 #include <linux/init.h> ··· 21 19 #include <linux/err.h> 22 20 #include <linux/pwm.h> 23 21 #include <linux/pwm_backlight.h> 22 + #include <linux/regulator/consumer.h> 24 23 #include <linux/slab.h> 25 24 26 25 struct pwm_bl_data { ··· 30 27 unsigned int period; 31 28 unsigned int lth_brightness; 32 29 unsigned int *levels; 30 + bool enabled; 31 + struct regulator *power_supply; 32 + int enable_gpio; 33 + unsigned long enable_gpio_flags; 34 + unsigned int scale; 33 35 int (*notify)(struct device *, 34 36 int brightness); 35 37 void (*notify_after)(struct device *, ··· 43 35 void (*exit)(struct device *); 44 36 }; 45 37 38 + static void pwm_backlight_power_on(struct pwm_bl_data *pb, int brightness) 39 + { 40 + int err; 41 + 42 + if (pb->enabled) 43 + return; 44 + 45 + err = regulator_enable(pb->power_supply); 46 + if (err < 0) 47 + dev_err(pb->dev, "failed to enable power supply\n"); 48 + 49 + if (gpio_is_valid(pb->enable_gpio)) { 50 + if (pb->enable_gpio_flags & PWM_BACKLIGHT_GPIO_ACTIVE_LOW) 51 + gpio_set_value(pb->enable_gpio, 0); 52 + else 53 + gpio_set_value(pb->enable_gpio, 1); 54 + } 55 + 56 + pwm_enable(pb->pwm); 57 + pb->enabled = true; 58 + } 59 + 60 + static void pwm_backlight_power_off(struct pwm_bl_data *pb) 61 + { 62 + if (!pb->enabled) 63 + return; 64 + 65 + pwm_config(pb->pwm, 0, pb->period); 66 + pwm_disable(pb->pwm); 67 + 68 + if (gpio_is_valid(pb->enable_gpio)) { 69 + if (pb->enable_gpio_flags & PWM_BACKLIGHT_GPIO_ACTIVE_LOW) 70 + gpio_set_value(pb->enable_gpio, 1); 71 + else 72 + gpio_set_value(pb->enable_gpio, 0); 73 + } 74 + 75 + regulator_disable(pb->power_supply); 76 + pb->enabled = false; 77 + } 78 + 79 + static int compute_duty_cycle(struct pwm_bl_data *pb, int brightness) 80 + { 81 + unsigned int lth = pb->lth_brightness; 82 + int duty_cycle; 83 + 84 + if (pb->levels) 85 + duty_cycle = pb->levels[brightness]; 86 + else 87 + duty_cycle = brightness; 88 + 89 + return (duty_cycle * (pb->period - lth) / pb->scale) + lth; 90 + } 91 + 46 92 static int pwm_backlight_update_status(struct backlight_device *bl) 47 93 { 48 94 struct pwm_bl_data *pb = bl_get_data(bl); 49 95 int brightness = bl->props.brightness; 50 - int max = bl->props.max_brightness; 96 + int duty_cycle; 51 97 52 98 if (bl->props.power != FB_BLANK_UNBLANK || 53 99 bl->props.fb_blank != FB_BLANK_UNBLANK || ··· 111 49 if (pb->notify) 112 50 brightness = pb->notify(pb->dev, brightness); 113 51 114 - if (brightness == 0) { 115 - pwm_config(pb->pwm, 0, pb->period); 116 - pwm_disable(pb->pwm); 117 - } else { 118 - int duty_cycle; 119 - 120 - if (pb->levels) { 121 - duty_cycle = pb->levels[brightness]; 122 - max = pb->levels[max]; 123 - } else { 124 - duty_cycle = brightness; 125 - } 126 - 127 - duty_cycle = pb->lth_brightness + 128 - (duty_cycle * (pb->period - pb->lth_brightness) / max); 52 + if (brightness > 0) { 53 + duty_cycle = compute_duty_cycle(pb, brightness); 129 54 pwm_config(pb->pwm, duty_cycle, pb->period); 130 - pwm_enable(pb->pwm); 131 - } 55 + pwm_backlight_power_on(pb, brightness); 56 + } else 57 + pwm_backlight_power_off(pb); 132 58 133 59 if (pb->notify_after) 134 60 pb->notify_after(pb->dev, brightness); ··· 148 98 struct platform_pwm_backlight_data *data) 149 99 { 150 100 struct device_node *node = dev->of_node; 101 + enum of_gpio_flags flags; 151 102 struct property *prop; 152 103 int length; 153 104 u32 value; ··· 189 138 data->max_brightness--; 190 139 } 191 140 192 - /* 193 - * TODO: Most users of this driver use a number of GPIOs to control 194 - * backlight power. Support for specifying these needs to be 195 - * added. 196 - */ 141 + data->enable_gpio = of_get_named_gpio_flags(node, "enable-gpios", 0, 142 + &flags); 143 + if (data->enable_gpio == -EPROBE_DEFER) 144 + return -EPROBE_DEFER; 145 + 146 + if (gpio_is_valid(data->enable_gpio) && (flags & OF_GPIO_ACTIVE_LOW)) 147 + data->enable_gpio_flags |= PWM_BACKLIGHT_GPIO_ACTIVE_LOW; 197 148 198 149 return 0; 199 150 } ··· 221 168 struct backlight_properties props; 222 169 struct backlight_device *bl; 223 170 struct pwm_bl_data *pb; 224 - unsigned int max; 225 171 int ret; 226 172 227 173 if (!data) { ··· 247 195 } 248 196 249 197 if (data->levels) { 250 - max = data->levels[data->max_brightness]; 198 + unsigned int i; 199 + 200 + for (i = 0; i <= data->max_brightness; i++) 201 + if (data->levels[i] > pb->scale) 202 + pb->scale = data->levels[i]; 203 + 251 204 pb->levels = data->levels; 252 205 } else 253 - max = data->max_brightness; 206 + pb->scale = data->max_brightness; 254 207 208 + pb->enable_gpio = data->enable_gpio; 209 + pb->enable_gpio_flags = data->enable_gpio_flags; 255 210 pb->notify = data->notify; 256 211 pb->notify_after = data->notify_after; 257 212 pb->check_fb = data->check_fb; 258 213 pb->exit = data->exit; 259 214 pb->dev = &pdev->dev; 215 + pb->enabled = false; 216 + 217 + if (gpio_is_valid(pb->enable_gpio)) { 218 + unsigned long flags; 219 + 220 + if (pb->enable_gpio_flags & PWM_BACKLIGHT_GPIO_ACTIVE_LOW) 221 + flags = GPIOF_OUT_INIT_HIGH; 222 + else 223 + flags = GPIOF_OUT_INIT_LOW; 224 + 225 + ret = gpio_request_one(pb->enable_gpio, flags, "enable"); 226 + if (ret < 0) { 227 + dev_err(&pdev->dev, "failed to request GPIO#%d: %d\n", 228 + pb->enable_gpio, ret); 229 + goto err_alloc; 230 + } 231 + } 232 + 233 + pb->power_supply = devm_regulator_get(&pdev->dev, "power"); 234 + if (IS_ERR(pb->power_supply)) { 235 + ret = PTR_ERR(pb->power_supply); 236 + goto err_gpio; 237 + } 260 238 261 239 pb->pwm = devm_pwm_get(&pdev->dev, NULL); 262 240 if (IS_ERR(pb->pwm)) { ··· 296 214 if (IS_ERR(pb->pwm)) { 297 215 dev_err(&pdev->dev, "unable to request legacy PWM\n"); 298 216 ret = PTR_ERR(pb->pwm); 299 - goto err_alloc; 217 + goto err_gpio; 300 218 } 301 219 } 302 220 ··· 311 229 pwm_set_period(pb->pwm, data->pwm_period_ns); 312 230 313 231 pb->period = pwm_get_period(pb->pwm); 314 - pb->lth_brightness = data->lth_brightness * (pb->period / max); 232 + pb->lth_brightness = data->lth_brightness * (pb->period / pb->scale); 315 233 316 234 memset(&props, 0, sizeof(struct backlight_properties)); 317 235 props.type = BACKLIGHT_RAW; ··· 321 239 if (IS_ERR(bl)) { 322 240 dev_err(&pdev->dev, "failed to register backlight\n"); 323 241 ret = PTR_ERR(bl); 324 - goto err_alloc; 242 + goto err_gpio; 325 243 } 326 244 327 245 if (data->dft_brightness > data->max_brightness) { ··· 337 255 platform_set_drvdata(pdev, bl); 338 256 return 0; 339 257 258 + err_gpio: 259 + if (gpio_is_valid(pb->enable_gpio)) 260 + gpio_free(pb->enable_gpio); 340 261 err_alloc: 341 262 if (data->exit) 342 263 data->exit(&pdev->dev); ··· 352 267 struct pwm_bl_data *pb = bl_get_data(bl); 353 268 354 269 backlight_device_unregister(bl); 355 - pwm_config(pb->pwm, 0, pb->period); 356 - pwm_disable(pb->pwm); 270 + pwm_backlight_power_off(pb); 271 + 357 272 if (pb->exit) 358 273 pb->exit(&pdev->dev); 274 + 359 275 return 0; 360 276 } 361 277 ··· 368 282 369 283 if (pb->notify) 370 284 pb->notify(pb->dev, 0); 371 - pwm_config(pb->pwm, 0, pb->period); 372 - pwm_disable(pb->pwm); 285 + 286 + pwm_backlight_power_off(pb); 287 + 373 288 if (pb->notify_after) 374 289 pb->notify_after(pb->dev, 0); 290 + 375 291 return 0; 376 292 } 377 293 ··· 382 294 struct backlight_device *bl = dev_get_drvdata(dev); 383 295 384 296 backlight_update_status(bl); 297 + 385 298 return 0; 386 299 } 387 300 #endif 388 301 389 - static SIMPLE_DEV_PM_OPS(pwm_backlight_pm_ops, pwm_backlight_suspend, 390 - pwm_backlight_resume); 302 + static const struct dev_pm_ops pwm_backlight_pm_ops = { 303 + #ifdef CONFIG_PM_SLEEP 304 + .suspend = pwm_backlight_suspend, 305 + .resume = pwm_backlight_resume, 306 + .poweroff = pwm_backlight_suspend, 307 + .restore = pwm_backlight_resume, 308 + #endif 309 + }; 391 310 392 311 static struct platform_driver pwm_backlight_driver = { 393 312 .driver = { ··· 412 317 MODULE_DESCRIPTION("PWM based Backlight Driver"); 413 318 MODULE_LICENSE("GPL"); 414 319 MODULE_ALIAS("platform:pwm-backlight"); 415 -
+5
include/linux/pwm_backlight.h
··· 6 6 7 7 #include <linux/backlight.h> 8 8 9 + /* TODO: convert to gpiod_*() API once it has been merged */ 10 + #define PWM_BACKLIGHT_GPIO_ACTIVE_LOW (1 << 0) 11 + 9 12 struct platform_pwm_backlight_data { 10 13 int pwm_id; 11 14 unsigned int max_brightness; ··· 16 13 unsigned int lth_brightness; 17 14 unsigned int pwm_period_ns; 18 15 unsigned int *levels; 16 + int enable_gpio; 17 + unsigned long enable_gpio_flags; 19 18 int (*init)(struct device *dev); 20 19 int (*notify)(struct device *dev, int brightness); 21 20 void (*notify_after)(struct device *dev, int brightness);