Merge tag 'backlight-next-4.18' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 11 Jun 2018 14:23:19 +0000 (07:23 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 11 Jun 2018 14:23:19 +0000 (07:23 -0700)
Pull backlight updates from Lee Jones:
 "Core Frameworks
   - Provide helpers to enable/disable backlight
   - Provide standard and devres versions OF find helpers

  New Drivers:
   - Add support for the Zodiac Inflight Innovations RAVE Supervisory
     Processor

  New Functionality:
   - Allow pwm-on/pwm-off delay to be specified via DT

  Bug Fixes:
   - Fix ordering of the power {en,dis}able and PWM {en,dis}able
     signals
   - Fix Device Tree node look-up"

* tag 'backlight-next-4.18' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/backlight:
  backlight: as3711_bl: Fix Device Tree node leaks
  backlight: tps65217_bl: Fix Device Tree node lookup
  backlight: max8925_bl: Fix Device Tree node lookup
  backlight: as3711_bl: Fix Device Tree node lookup
  MAINTAINERS: Add dri-devel for backlight subsystem patches
  backlight: Nuke BL_CORE_DRIVER1
  staging: fbtft: Stop using BL_CORE_DRIVER1
  backlight: pandora: Stop using BL_CORE_DRIVER1
  backlight: generic-bl: Remove DRIVER1 state
  backlight: Nuke unused backlight.props.state states
  backlight: otm3225a: Add support for ORISE OTM3225A LCD SoC
  backlight: pwm_bl: Don't use GPIOF_* with gpiod_get_direction
  pwm-backlight: Add support for PWM delays proprieties.
  dt-bindings: pwm-backlight: Add PWM delay proprieties.
  pwm-backlight: Enable/disable the PWM before/after LCD enable toggle.
  dt-bindings: backlight: Add binding for RAVE SP backlight driver
  backlight: Add RAVE SP backlight driver

19 files changed:
Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt
Documentation/devicetree/bindings/leds/backlight/zii,rave-sp-backlight.txt [new file with mode: 0644]
MAINTAINERS
drivers/staging/fbtft/fbtft-core.c
drivers/staging/fbtft/fbtft.h
drivers/video/backlight/Kconfig
drivers/video/backlight/Makefile
drivers/video/backlight/as3711_bl.c
drivers/video/backlight/generic_bl.c
drivers/video/backlight/max8925_bl.c
drivers/video/backlight/otm3225a.c [new file with mode: 0644]
drivers/video/backlight/pandora_bl.c
drivers/video/backlight/pwm_bl.c
drivers/video/backlight/rave-sp-backlight.c [new file with mode: 0644]
drivers/video/backlight/tps65217_bl.c
include/linux/backlight.h
include/linux/mfd/as3711.h
include/linux/mfd/rave-sp.h
include/linux/pwm_backlight.h

index 764db86d441ad131aceca0e15146d5c914d97919..3108109066132698eaaff2606cd4a652d708a202 100644 (file)
@@ -17,6 +17,10 @@ Optional properties:
                "pwms" property (see PWM binding[0])
   - enable-gpios: contains a single GPIO specifier for the GPIO which enables
                   and disables the backlight (see GPIO binding[1])
+  - post-pwm-on-delay-ms: Delay in ms between setting an initial (non-zero) PWM
+                          and enabling the backlight using GPIO.
+  - pwm-off-delay-ms: Delay in ms between disabling the backlight using GPIO
+                      and setting PWM value to 0.
 
 [0]: Documentation/devicetree/bindings/pwm/pwm.txt
 [1]: Documentation/devicetree/bindings/gpio/gpio.txt
@@ -32,4 +36,6 @@ Example:
 
                power-supply = <&vdd_bl_reg>;
                enable-gpios = <&gpio 58 0>;
+               post-pwm-on-delay-ms = <10>;
+               pwm-off-delay-ms = <10>;
        };
diff --git a/Documentation/devicetree/bindings/leds/backlight/zii,rave-sp-backlight.txt b/Documentation/devicetree/bindings/leds/backlight/zii,rave-sp-backlight.txt
new file mode 100644 (file)
index 0000000..ff5c921
--- /dev/null
@@ -0,0 +1,23 @@
+Zodiac Inflight Innovations RAVE Supervisory Processor Backlight Bindings
+
+RAVE SP backlight device is a "MFD cell" device corresponding to
+backlight functionality of RAVE Supervisory Processor. It is expected
+that its Device Tree node is specified as a child of the node
+corresponding to the parent RAVE SP device (as documented in
+Documentation/devicetree/bindings/mfd/zii,rave-sp.txt)
+
+Required properties:
+
+- compatible: Should be "zii,rave-sp-backlight"
+
+Example:
+
+       rave-sp {
+               compatible = "zii,rave-sp-rdu1";
+               current-speed = <38400>;
+
+               backlight {
+                       compatible = "zii,rave-sp-backlight";
+               };
+       }
+
index 8fcfc9a4a71db57fc5dcf9bdc5a74b4f7a7f3f49..868be4ab62dbc4100f79113d8a53cb4c90026d4f 100644 (file)
@@ -2606,6 +2606,7 @@ BACKLIGHT CLASS/SUBSYSTEM
 M:     Lee Jones <lee.jones@linaro.org>
 M:     Daniel Thompson <daniel.thompson@linaro.org>
 M:     Jingoo Han <jingoohan1@gmail.com>
+L:     dri-devel@lists.freedesktop.org
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/lee/backlight.git
 S:     Maintained
 F:     drivers/video/backlight/
index 0e36b66ae5f75d58a9216569d7f86a3da991fbbf..731e47149af8072318045e18efee2379aa6de540 100644 (file)
@@ -246,7 +246,7 @@ static int fbtft_request_gpios_dt(struct fbtft_par *par)
 static int fbtft_backlight_update_status(struct backlight_device *bd)
 {
        struct fbtft_par *par = bl_get_data(bd);
-       bool polarity = !!(bd->props.state & BL_CORE_DRIVER1);
+       bool polarity = par->polarity;
 
        fbtft_par_dbg(DEBUG_BACKLIGHT, par,
                "%s: polarity=%d, power=%d, fb_blank=%d\n",
@@ -296,7 +296,7 @@ void fbtft_register_backlight(struct fbtft_par *par)
        /* Assume backlight is off, get polarity from current state of pin */
        bl_props.power = FB_BLANK_POWERDOWN;
        if (!gpio_get_value(par->gpio.led[0]))
-               bl_props.state |= BL_CORE_DRIVER1;
+               par->polarity = true;
 
        bd = backlight_device_register(dev_driver_string(par->info->device),
                                       par->info->device, par,
index e19e64e0d094c26078c45b1ff7df924a62962a3c..c7cb4a7896f478f1765f9b5d2b6442ec27f342ba 100644 (file)
@@ -229,6 +229,7 @@ struct fbtft_par {
        ktime_t update_time;
        bool bgr;
        void *extra;
+       bool polarity;
 };
 
 #define NUMARGS(...)  (sizeof((int[]){__VA_ARGS__})/sizeof(int))
index 4e1d2ad50ba142950e0048d986ab7e0df2eafece..2919e23340527704ea5ca9d1607f76b6e1e45cbc 100644 (file)
@@ -150,6 +150,13 @@ config LCD_HX8357
          If you have a HX-8357 LCD panel, say Y to enable its LCD control
          driver.
 
+  config LCD_OTM3225A
+       tristate "ORISE Technology OTM3225A support"
+       depends on SPI
+       help
+         If you have a panel based on the OTM3225A controller
+         chip then say y to include a driver for it.
+
 endif # LCD_CLASS_DEVICE
 
 #
@@ -467,6 +474,12 @@ config BACKLIGHT_ARCXCNN
          If you have an ARCxCnnnn family backlight say Y to enable
          the backlight driver.
 
+config BACKLIGHT_RAVE_SP
+       tristate "RAVE SP Backlight driver"
+       depends on RAVE_SP_CORE
+       help
+         Support for backlight control on RAVE SP device.
+
 endif # BACKLIGHT_CLASS_DEVICE
 
 endif # BACKLIGHT_LCD_SUPPORT
index 5e28f01c839107ef8e9cca3225181f46b953545e..0dcc2c745c03c4781875f898e3aeb7a41b1264f0 100644 (file)
@@ -13,6 +13,7 @@ obj-$(CONFIG_LCD_LD9040)              += ld9040.o
 obj-$(CONFIG_LCD_LMS283GF05)           += lms283gf05.o
 obj-$(CONFIG_LCD_LMS501KF03)           += lms501kf03.o
 obj-$(CONFIG_LCD_LTV350QV)             += ltv350qv.o
+obj-$(CONFIG_LCD_OTM3225A)             += otm3225a.o
 obj-$(CONFIG_LCD_PLATFORM)             += platform_lcd.o
 obj-$(CONFIG_LCD_S6E63M0)              += s6e63m0.o
 obj-$(CONFIG_LCD_TDO24M)               += tdo24m.o
@@ -57,3 +58,4 @@ obj-$(CONFIG_BACKLIGHT_TOSA)          += tosa_bl.o
 obj-$(CONFIG_BACKLIGHT_TPS65217)       += tps65217_bl.o
 obj-$(CONFIG_BACKLIGHT_WM831X)         += wm831x_bl.o
 obj-$(CONFIG_BACKLIGHT_ARCXCNN)        += arcxcnn_bl.o
+obj-$(CONFIG_BACKLIGHT_RAVE_SP)                += rave-sp-backlight.o
index 734a9158946b1f805a3738d9e9c31f25cf8b3314..ca544aa764b8e6b6b067395f409494767382bd1d 100644 (file)
@@ -28,8 +28,6 @@ enum as3711_bl_type {
 
 struct as3711_bl_data {
        bool powered;
-       const char *fb_name;
-       struct device *fb_dev;
        enum as3711_bl_type type;
        int brightness;
        struct backlight_device *bl;
@@ -262,10 +260,10 @@ static int as3711_bl_register(struct platform_device *pdev,
 static int as3711_backlight_parse_dt(struct device *dev)
 {
        struct as3711_bl_pdata *pdata = dev_get_platdata(dev);
-       struct device_node *bl =
-               of_find_node_by_name(dev->parent->of_node, "backlight"), *fb;
+       struct device_node *bl, *fb;
        int ret;
 
+       bl = of_get_child_by_name(dev->parent->of_node, "backlight");
        if (!bl) {
                dev_dbg(dev, "backlight node not found\n");
                return -ENODEV;
@@ -273,26 +271,30 @@ static int as3711_backlight_parse_dt(struct device *dev)
 
        fb = of_parse_phandle(bl, "su1-dev", 0);
        if (fb) {
-               pdata->su1_fb = fb->full_name;
+               of_node_put(fb);
+
+               pdata->su1_fb = true;
 
                ret = of_property_read_u32(bl, "su1-max-uA", &pdata->su1_max_uA);
                if (pdata->su1_max_uA <= 0)
                        ret = -EINVAL;
                if (ret < 0)
-                       return ret;
+                       goto err_put_bl;
        }
 
        fb = of_parse_phandle(bl, "su2-dev", 0);
        if (fb) {
                int count = 0;
 
-               pdata->su2_fb = fb->full_name;
+               of_node_put(fb);
+
+               pdata->su2_fb = true;
 
                ret = of_property_read_u32(bl, "su2-max-uA", &pdata->su2_max_uA);
                if (pdata->su2_max_uA <= 0)
                        ret = -EINVAL;
                if (ret < 0)
-                       return ret;
+                       goto err_put_bl;
 
                if (of_find_property(bl, "su2-feedback-voltage", NULL)) {
                        pdata->su2_feedback = AS3711_SU2_VOLTAGE;
@@ -314,8 +316,10 @@ static int as3711_backlight_parse_dt(struct device *dev)
                        pdata->su2_feedback = AS3711_SU2_CURR_AUTO;
                        count++;
                }
-               if (count != 1)
-                       return -EINVAL;
+               if (count != 1) {
+                       ret = -EINVAL;
+                       goto err_put_bl;
+               }
 
                count = 0;
                if (of_find_property(bl, "su2-fbprot-lx-sd4", NULL)) {
@@ -334,8 +338,10 @@ static int as3711_backlight_parse_dt(struct device *dev)
                        pdata->su2_fbprot = AS3711_SU2_GPIO4;
                        count++;
                }
-               if (count != 1)
-                       return -EINVAL;
+               if (count != 1) {
+                       ret = -EINVAL;
+                       goto err_put_bl;
+               }
 
                count = 0;
                if (of_find_property(bl, "su2-auto-curr1", NULL)) {
@@ -355,11 +361,20 @@ static int as3711_backlight_parse_dt(struct device *dev)
                 * At least one su2-auto-curr* must be specified iff
                 * AS3711_SU2_CURR_AUTO is used
                 */
-               if (!count ^ (pdata->su2_feedback != AS3711_SU2_CURR_AUTO))
-                       return -EINVAL;
+               if (!count ^ (pdata->su2_feedback != AS3711_SU2_CURR_AUTO)) {
+                       ret = -EINVAL;
+                       goto err_put_bl;
+               }
        }
 
+       of_node_put(bl);
+
        return 0;
+
+err_put_bl:
+       of_node_put(bl);
+
+       return ret;
 }
 
 static int as3711_backlight_probe(struct platform_device *pdev)
@@ -412,7 +427,6 @@ static int as3711_backlight_probe(struct platform_device *pdev)
 
        if (pdata->su1_fb) {
                su = &supply->su1;
-               su->fb_name = pdata->su1_fb;
                su->type = AS3711_BL_SU1;
 
                max_brightness = min(pdata->su1_max_uA, 31);
@@ -423,7 +437,6 @@ static int as3711_backlight_probe(struct platform_device *pdev)
 
        if (pdata->su2_fb) {
                su = &supply->su2;
-               su->fb_name = pdata->su2_fb;
                su->type = AS3711_BL_SU2;
 
                switch (pdata->su2_fbprot) {
index 67dfb939a51428f1fb1a54381bfde0b56d53fe8e..4dea91acea138037f29f07423375b06cebf7ab9a 100644 (file)
@@ -21,9 +21,6 @@ static int genericbl_intensity;
 static struct backlight_device *generic_backlight_device;
 static struct generic_bl_info *bl_machinfo;
 
-/* Flag to signal when the battery is low */
-#define GENERICBL_BATTLOW       BL_CORE_DRIVER1
-
 static int genericbl_send_intensity(struct backlight_device *bd)
 {
        int intensity = bd->props.brightness;
@@ -34,8 +31,6 @@ static int genericbl_send_intensity(struct backlight_device *bd)
                intensity = 0;
        if (bd->props.state & BL_CORE_SUSPENDED)
                intensity = 0;
-       if (bd->props.state & GENERICBL_BATTLOW)
-               intensity &= bl_machinfo->limit_mask;
 
        bl_machinfo->set_bl_intensity(intensity);
 
index 7b738d60ecc22e27560e42c9cef0669628e4aa28..f3aa6088f1d97805f23b9780a1db893cf1a46b00 100644 (file)
@@ -116,7 +116,7 @@ static void max8925_backlight_dt_init(struct platform_device *pdev)
        if (!pdata)
                return;
 
-       np = of_find_node_by_name(nproot, "backlight");
+       np = of_get_child_by_name(nproot, "backlight");
        if (!np) {
                dev_err(&pdev->dev, "failed to find backlight node\n");
                return;
@@ -125,6 +125,8 @@ static void max8925_backlight_dt_init(struct platform_device *pdev)
        if (!of_property_read_u32(np, "maxim,max8925-dual-string", &val))
                pdata->dual_string = val;
 
+       of_node_put(np);
+
        pdev->dev.platform_data = pdata;
 }
 
diff --git a/drivers/video/backlight/otm3225a.c b/drivers/video/backlight/otm3225a.c
new file mode 100644 (file)
index 0000000..2472e21
--- /dev/null
@@ -0,0 +1,252 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Driver for ORISE Technology OTM3225A SOC for TFT LCD
+ * Copyright (C) 2017, EETS GmbH, Felix Brack <fb@ltec.ch>
+ *
+ * This driver implements a lcd device for the ORISE OTM3225A display
+ * controller. The control interface to the display is SPI and the display's
+ * memory is updated over the 16-bit RGB interface.
+ * The main source of information for writing this driver was provided by the
+ * OTM3225A datasheet from ORISE Technology. Some information arise from the
+ * ILI9328 datasheet from ILITEK as well as from the datasheets and sample code
+ * provided by Crystalfontz America Inc. who sells the CFAF240320A-032T, a 3.2"
+ * TFT LC display using the OTM3225A controller.
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/lcd.h>
+#include <linux/module.h>
+#include <linux/spi/spi.h>
+
+#define OTM3225A_INDEX_REG     0x70
+#define OTM3225A_DATA_REG      0x72
+
+/* instruction register list */
+#define DRIVER_OUTPUT_CTRL_1   0x01
+#define DRIVER_WAVEFORM_CTRL   0x02
+#define ENTRY_MODE             0x03
+#define SCALING_CTRL           0x04
+#define DISPLAY_CTRL_1         0x07
+#define DISPLAY_CTRL_2         0x08
+#define DISPLAY_CTRL_3         0x09
+#define FRAME_CYCLE_CTRL       0x0A
+#define EXT_DISP_IFACE_CTRL_1  0x0C
+#define FRAME_MAKER_POS                0x0D
+#define EXT_DISP_IFACE_CTRL_2  0x0F
+#define POWER_CTRL_1           0x10
+#define POWER_CTRL_2           0x11
+#define POWER_CTRL_3           0x12
+#define POWER_CTRL_4           0x13
+#define GRAM_ADDR_HORIZ_SET    0x20
+#define GRAM_ADDR_VERT_SET     0x21
+#define GRAM_READ_WRITE                0x22
+#define POWER_CTRL_7           0x29
+#define FRAME_RATE_CTRL                0x2B
+#define GAMMA_CTRL_1           0x30
+#define GAMMA_CTRL_2           0x31
+#define GAMMA_CTRL_3           0x32
+#define GAMMA_CTRL_4           0x35
+#define GAMMA_CTRL_5           0x36
+#define GAMMA_CTRL_6           0x37
+#define GAMMA_CTRL_7           0x38
+#define GAMMA_CTRL_8           0x39
+#define GAMMA_CTRL_9           0x3C
+#define GAMMA_CTRL_10          0x3D
+#define WINDOW_HORIZ_RAM_START 0x50
+#define WINDOW_HORIZ_RAM_END   0x51
+#define WINDOW_VERT_RAM_START  0x52
+#define WINDOW_VERT_RAM_END    0x53
+#define DRIVER_OUTPUT_CTRL_2   0x60
+#define BASE_IMG_DISPLAY_CTRL  0x61
+#define VERT_SCROLL_CTRL       0x6A
+#define PD1_DISPLAY_POS                0x80
+#define PD1_RAM_START          0x81
+#define PD1_RAM_END            0x82
+#define PD2_DISPLAY_POS                0x83
+#define PD2_RAM_START          0x84
+#define PD2_RAM_END            0x85
+#define PANEL_IFACE_CTRL_1     0x90
+#define PANEL_IFACE_CTRL_2     0x92
+#define PANEL_IFACE_CTRL_4     0x95
+#define PANEL_IFACE_CTRL_5     0x97
+
+struct otm3225a_data {
+       struct spi_device *spi;
+       struct lcd_device *ld;
+       int power;
+};
+
+struct otm3225a_spi_instruction {
+       unsigned char reg;      /* register to write */
+       unsigned short value;   /* data to write to 'reg' */
+       unsigned short delay;   /* delay in ms after write */
+};
+
+static struct otm3225a_spi_instruction display_init[] = {
+       { DRIVER_OUTPUT_CTRL_1,         0x0000, 0 },
+       { DRIVER_WAVEFORM_CTRL,         0x0700, 0 },
+       { ENTRY_MODE,                   0x50A0, 0 },
+       { SCALING_CTRL,                 0x0000, 0 },
+       { DISPLAY_CTRL_2,               0x0606, 0 },
+       { DISPLAY_CTRL_3,               0x0000, 0 },
+       { FRAME_CYCLE_CTRL,             0x0000, 0 },
+       { EXT_DISP_IFACE_CTRL_1,        0x0000, 0 },
+       { FRAME_MAKER_POS,              0x0000, 0 },
+       { EXT_DISP_IFACE_CTRL_2,        0x0002, 0 },
+       { POWER_CTRL_2,                 0x0007, 0 },
+       { POWER_CTRL_3,                 0x0000, 0 },
+       { POWER_CTRL_4,                 0x0000, 200 },
+       { DISPLAY_CTRL_1,               0x0101, 0 },
+       { POWER_CTRL_1,                 0x12B0, 0 },
+       { POWER_CTRL_2,                 0x0007, 0 },
+       { POWER_CTRL_3,                 0x01BB, 50 },
+       { POWER_CTRL_4,                 0x0013, 0 },
+       { POWER_CTRL_7,                 0x0010, 50 },
+       { GAMMA_CTRL_1,                 0x000A, 0 },
+       { GAMMA_CTRL_2,                 0x1326, 0 },
+       { GAMMA_CTRL_3,                 0x0A29, 0 },
+       { GAMMA_CTRL_4,                 0x0A0A, 0 },
+       { GAMMA_CTRL_5,                 0x1E03, 0 },
+       { GAMMA_CTRL_6,                 0x031E, 0 },
+       { GAMMA_CTRL_7,                 0x0706, 0 },
+       { GAMMA_CTRL_8,                 0x0303, 0 },
+       { GAMMA_CTRL_9,                 0x010E, 0 },
+       { GAMMA_CTRL_10,                0x040E, 0 },
+       { WINDOW_HORIZ_RAM_START,       0x0000, 0 },
+       { WINDOW_HORIZ_RAM_END,         0x00EF, 0 },
+       { WINDOW_VERT_RAM_START,        0x0000, 0 },
+       { WINDOW_VERT_RAM_END,          0x013F, 0 },
+       { DRIVER_OUTPUT_CTRL_2,         0x2700, 0 },
+       { BASE_IMG_DISPLAY_CTRL,        0x0001, 0 },
+       { VERT_SCROLL_CTRL,             0x0000, 0 },
+       { PD1_DISPLAY_POS,              0x0000, 0 },
+       { PD1_RAM_START,                0x0000, 0 },
+       { PD1_RAM_END,                  0x0000, 0 },
+       { PD2_DISPLAY_POS,              0x0000, 0 },
+       { PD2_RAM_START,                0x0000, 0 },
+       { PD2_RAM_END,                  0x0000, 0 },
+       { PANEL_IFACE_CTRL_1,           0x0010, 0 },
+       { PANEL_IFACE_CTRL_2,           0x0000, 0 },
+       { PANEL_IFACE_CTRL_4,           0x0210, 0 },
+       { PANEL_IFACE_CTRL_5,           0x0000, 0 },
+       { DISPLAY_CTRL_1,               0x0133, 0 },
+};
+
+static struct otm3225a_spi_instruction display_enable_rgb_interface[] = {
+       { ENTRY_MODE,                   0x1080, 0 },
+       { GRAM_ADDR_HORIZ_SET,          0x0000, 0 },
+       { GRAM_ADDR_VERT_SET,           0x0000, 0 },
+       { EXT_DISP_IFACE_CTRL_1,        0x0111, 500 },
+};
+
+static struct otm3225a_spi_instruction display_off[] = {
+       { DISPLAY_CTRL_1,       0x0131, 100 },
+       { DISPLAY_CTRL_1,       0x0130, 100 },
+       { DISPLAY_CTRL_1,       0x0100, 0 },
+       { POWER_CTRL_1,         0x0280, 0 },
+       { POWER_CTRL_3,         0x018B, 0 },
+};
+
+static struct otm3225a_spi_instruction display_on[] = {
+       { POWER_CTRL_1,         0x1280, 0 },
+       { DISPLAY_CTRL_1,       0x0101, 100 },
+       { DISPLAY_CTRL_1,       0x0121, 0 },
+       { DISPLAY_CTRL_1,       0x0123, 100 },
+       { DISPLAY_CTRL_1,       0x0133, 10 },
+};
+
+static void otm3225a_write(struct spi_device *spi,
+                          struct otm3225a_spi_instruction *instruction,
+                          unsigned int count)
+{
+       unsigned char buf[3];
+
+       while (count--) {
+               /* address register using index register */
+               buf[0] = OTM3225A_INDEX_REG;
+               buf[1] = 0x00;
+               buf[2] = instruction->reg;
+               spi_write(spi, buf, 3);
+
+               /* write data to addressed register */
+               buf[0] = OTM3225A_DATA_REG;
+               buf[1] = (instruction->value >> 8) & 0xff;
+               buf[2] = instruction->value & 0xff;
+               spi_write(spi, buf, 3);
+
+               /* execute delay if any */
+               if (instruction->delay)
+                       msleep(instruction->delay);
+               instruction++;
+       }
+}
+
+static int otm3225a_set_power(struct lcd_device *ld, int power)
+{
+       struct otm3225a_data *dd = lcd_get_data(ld);
+
+       if (power == dd->power)
+               return 0;
+
+       if (power > FB_BLANK_UNBLANK)
+               otm3225a_write(dd->spi, display_off, ARRAY_SIZE(display_off));
+       else
+               otm3225a_write(dd->spi, display_on, ARRAY_SIZE(display_on));
+       dd->power = power;
+
+       return 0;
+}
+
+static int otm3225a_get_power(struct lcd_device *ld)
+{
+       struct otm3225a_data *dd = lcd_get_data(ld);
+
+       return dd->power;
+}
+
+static struct lcd_ops otm3225a_ops = {
+       .set_power = otm3225a_set_power,
+       .get_power = otm3225a_get_power,
+};
+
+static int otm3225a_probe(struct spi_device *spi)
+{
+       struct otm3225a_data *dd;
+       struct lcd_device *ld;
+       struct device *dev = &spi->dev;
+
+       dd = devm_kzalloc(dev, sizeof(struct otm3225a_data), GFP_KERNEL);
+       if (dd == NULL)
+               return -ENOMEM;
+
+       ld = devm_lcd_device_register(dev, dev_name(dev), dev, dd,
+                                     &otm3225a_ops);
+       if (IS_ERR(ld))
+               return PTR_ERR(ld);
+
+       dd->spi = spi;
+       dd->ld = ld;
+       dev_set_drvdata(dev, dd);
+
+       dev_info(dev, "Initializing and switching to RGB interface");
+       otm3225a_write(spi, display_init, ARRAY_SIZE(display_init));
+       otm3225a_write(spi, display_enable_rgb_interface,
+                      ARRAY_SIZE(display_enable_rgb_interface));
+       return 0;
+}
+
+static struct spi_driver otm3225a_driver = {
+       .driver = {
+               .name = "otm3225a",
+               .owner = THIS_MODULE,
+       },
+       .probe = otm3225a_probe,
+};
+
+module_spi_driver(otm3225a_driver);
+
+MODULE_AUTHOR("Felix Brack <fb@ltec.ch>");
+MODULE_DESCRIPTION("OTM3225A TFT LCD driver");
+MODULE_VERSION("1.0.0");
+MODULE_LICENSE("GPL v2");
index a186bc677c7d8071a3bf23c3ef6b8b5b9278031b..9618766e38666d0a9da4fa8124471154f2938c2e 100644 (file)
 #define MAX_VALUE 63
 #define MAX_USER_VALUE (MAX_VALUE - MIN_VALUE)
 
-#define PANDORABL_WAS_OFF BL_CORE_DRIVER1
+struct pandora_private {
+       unsigned old_state;
+#define PANDORABL_WAS_OFF 1
+};
 
 static int pandora_backlight_update_status(struct backlight_device *bl)
 {
        int brightness = bl->props.brightness;
+       struct pandora_private *priv = bl_get_data(bl);
        u8 r;
 
        if (bl->props.power != FB_BLANK_UNBLANK)
@@ -53,7 +57,7 @@ static int pandora_backlight_update_status(struct backlight_device *bl)
                brightness = MAX_USER_VALUE;
 
        if (brightness == 0) {
-               if (bl->props.state & PANDORABL_WAS_OFF)
+               if (priv->old_state == PANDORABL_WAS_OFF)
                        goto done;
 
                /* first disable PWM0 output, then clock */
@@ -66,7 +70,7 @@ static int pandora_backlight_update_status(struct backlight_device *bl)
                goto done;
        }
 
-       if (bl->props.state & PANDORABL_WAS_OFF) {
+       if (priv->old_state == PANDORABL_WAS_OFF) {
                /*
                 * set PWM duty cycle to max. TPS61161 seems to use this
                 * to calibrate it's PWM sensitivity when it starts.
@@ -93,9 +97,9 @@ static int pandora_backlight_update_status(struct backlight_device *bl)
 
 done:
        if (brightness != 0)
-               bl->props.state &= ~PANDORABL_WAS_OFF;
+               priv->old_state = 0;
        else
-               bl->props.state |= PANDORABL_WAS_OFF;
+               priv->old_state = PANDORABL_WAS_OFF;
 
        return 0;
 }
@@ -109,13 +113,20 @@ static int pandora_backlight_probe(struct platform_device *pdev)
 {
        struct backlight_properties props;
        struct backlight_device *bl;
+       struct pandora_private *priv;
        u8 r;
 
+       priv = devm_kmalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv) {
+               dev_err(&pdev->dev, "failed to allocate driver private data\n");
+               return -ENOMEM;
+       }
+
        memset(&props, 0, sizeof(props));
        props.max_brightness = MAX_USER_VALUE;
        props.type = BACKLIGHT_RAW;
        bl = devm_backlight_device_register(&pdev->dev, pdev->name, &pdev->dev,
-                                       NULL, &pandora_backlight_ops, &props);
+                                       priv, &pandora_backlight_ops, &props);
        if (IS_ERR(bl)) {
                dev_err(&pdev->dev, "failed to register backlight\n");
                return PTR_ERR(bl);
@@ -126,7 +137,7 @@ static int pandora_backlight_probe(struct platform_device *pdev)
        /* 64 cycle period, ON position 0 */
        twl_i2c_write_u8(TWL_MODULE_PWM, 0x80, TWL_PWM0_ON);
 
-       bl->props.state |= PANDORABL_WAS_OFF;
+       priv->old_state = PANDORABL_WAS_OFF;
        bl->props.brightness = MAX_USER_VALUE;
        backlight_update_status(bl);
 
index 1c2289ddd555a64a418f29edeaf8e4b5643430b9..44ac5bde4e9d1ad6a39e32c57d3350ffe0bdd8ab 100644 (file)
@@ -10,6 +10,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/delay.h>
 #include <linux/gpio/consumer.h>
 #include <linux/gpio.h>
 #include <linux/module.h>
@@ -35,6 +36,8 @@ struct pwm_bl_data {
        struct gpio_desc        *enable_gpio;
        unsigned int            scale;
        bool                    legacy;
+       unsigned int            post_pwm_on_delay;
+       unsigned int            pwm_off_delay;
        int                     (*notify)(struct device *,
                                          int brightness);
        void                    (*notify_after)(struct device *,
@@ -54,10 +57,14 @@ static void pwm_backlight_power_on(struct pwm_bl_data *pb, int brightness)
        if (err < 0)
                dev_err(pb->dev, "failed to enable power supply\n");
 
+       pwm_enable(pb->pwm);
+
+       if (pb->post_pwm_on_delay)
+               msleep(pb->post_pwm_on_delay);
+
        if (pb->enable_gpio)
                gpiod_set_value_cansleep(pb->enable_gpio, 1);
 
-       pwm_enable(pb->pwm);
        pb->enabled = true;
 }
 
@@ -66,12 +73,15 @@ static void pwm_backlight_power_off(struct pwm_bl_data *pb)
        if (!pb->enabled)
                return;
 
-       pwm_config(pb->pwm, 0, pb->period);
-       pwm_disable(pb->pwm);
-
        if (pb->enable_gpio)
                gpiod_set_value_cansleep(pb->enable_gpio, 0);
 
+       if (pb->pwm_off_delay)
+               msleep(pb->pwm_off_delay);
+
+       pwm_config(pb->pwm, 0, pb->period);
+       pwm_disable(pb->pwm);
+
        regulator_disable(pb->power_supply);
        pb->enabled = false;
 }
@@ -177,6 +187,14 @@ static int pwm_backlight_parse_dt(struct device *dev,
                data->max_brightness--;
        }
 
+       /*
+        * These values are optional and set as 0 by default, the out values
+        * are modified only if a valid u32 value can be decoded.
+        */
+       of_property_read_u32(node, "post-pwm-on-delay-ms",
+                            &data->post_pwm_on_delay);
+       of_property_read_u32(node, "pwm-off-delay-ms", &data->pwm_off_delay);
+
        data->enable_gpio = -EINVAL;
        return 0;
 }
@@ -275,6 +293,8 @@ static int pwm_backlight_probe(struct platform_device *pdev)
        pb->exit = data->exit;
        pb->dev = &pdev->dev;
        pb->enabled = false;
+       pb->post_pwm_on_delay = data->post_pwm_on_delay;
+       pb->pwm_off_delay = data->pwm_off_delay;
 
        pb->enable_gpio = devm_gpiod_get_optional(&pdev->dev, "enable",
                                                  GPIOD_ASIS);
@@ -301,14 +321,14 @@ static int pwm_backlight_probe(struct platform_device *pdev)
 
        /*
         * If the GPIO is not known to be already configured as output, that
-        * is, if gpiod_get_direction returns either GPIOF_DIR_IN or -EINVAL,
-        * change the direction to output and set the GPIO as active.
+        * is, if gpiod_get_direction returns either 1 or -EINVAL, change the
+        * direction to output and set the GPIO as active.
         * Do not force the GPIO to active when it was already output as it
         * could cause backlight flickering or we would enable the backlight too
         * early. Leave the decision of the initial backlight state for later.
         */
        if (pb->enable_gpio &&
-           gpiod_get_direction(pb->enable_gpio) != GPIOF_DIR_OUT)
+           gpiod_get_direction(pb->enable_gpio) != 0)
                gpiod_direction_output(pb->enable_gpio, 1);
 
        pb->power_supply = devm_regulator_get(&pdev->dev, "power");
diff --git a/drivers/video/backlight/rave-sp-backlight.c b/drivers/video/backlight/rave-sp-backlight.c
new file mode 100644 (file)
index 0000000..462f14a
--- /dev/null
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/*
+ * LCD Backlight driver for RAVE SP
+ *
+ * Copyright (C) 2018 Zodiac Inflight Innovations
+ *
+ */
+
+#include <linux/backlight.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mfd/rave-sp.h>
+#include <linux/platform_device.h>
+
+#define        RAVE_SP_BACKLIGHT_LCD_EN        BIT(7)
+
+static int rave_sp_backlight_update_status(struct backlight_device *bd)
+{
+       const struct backlight_properties *p = &bd->props;
+       const u8 intensity =
+               (p->power == FB_BLANK_UNBLANK) ? p->brightness : 0;
+       struct rave_sp *sp = dev_get_drvdata(&bd->dev);
+       u8 cmd[] = {
+               [0] = RAVE_SP_CMD_SET_BACKLIGHT,
+               [1] = 0,
+               [2] = intensity ? RAVE_SP_BACKLIGHT_LCD_EN | intensity : 0,
+               [3] = 0,
+               [4] = 0,
+       };
+
+       return rave_sp_exec(sp, cmd, sizeof(cmd), NULL, 0);
+}
+
+static const struct backlight_ops rave_sp_backlight_ops = {
+       .options        = BL_CORE_SUSPENDRESUME,
+       .update_status  = rave_sp_backlight_update_status,
+};
+
+static struct backlight_properties rave_sp_backlight_props = {
+       .type           = BACKLIGHT_PLATFORM,
+       .max_brightness = 100,
+       .brightness     = 50,
+};
+
+static int rave_sp_backlight_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct backlight_device *bd;
+
+       bd = devm_backlight_device_register(dev, pdev->name, dev->parent,
+                                           dev_get_drvdata(dev->parent),
+                                           &rave_sp_backlight_ops,
+                                           &rave_sp_backlight_props);
+       if (IS_ERR(bd))
+               return PTR_ERR(bd);
+
+       backlight_update_status(bd);
+
+       return 0;
+}
+
+static const struct of_device_id rave_sp_backlight_of_match[] = {
+       { .compatible = "zii,rave-sp-backlight" },
+       {}
+};
+
+static struct platform_driver rave_sp_backlight_driver = {
+       .probe = rave_sp_backlight_probe,
+       .driver = {
+               .name = KBUILD_MODNAME,
+               .of_match_table = rave_sp_backlight_of_match,
+       },
+};
+module_platform_driver(rave_sp_backlight_driver);
+
+MODULE_DEVICE_TABLE(of, rave_sp_backlight_of_match);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Andrey Vostrikov <andrey.vostrikov@cogentembedded.com>");
+MODULE_AUTHOR("Nikita Yushchenko <nikita.yoush@cogentembedded.com>");
+MODULE_AUTHOR("Andrey Smirnov <andrew.smirnov@gmail.com>");
+MODULE_DESCRIPTION("RAVE SP Backlight driver");
index 380917c862769524c56687c0e5bf86c8fc339914..762e3feed097cbd581f721d389a13dd52aa57aca 100644 (file)
@@ -184,11 +184,11 @@ static struct tps65217_bl_pdata *
 tps65217_bl_parse_dt(struct platform_device *pdev)
 {
        struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent);
-       struct device_node *node = of_node_get(tps->dev->of_node);
+       struct device_node *node;
        struct tps65217_bl_pdata *pdata, *err;
        u32 val;
 
-       node = of_find_node_by_name(node, "backlight");
+       node = of_get_child_by_name(tps->dev->of_node, "backlight");
        if (!node)
                return ERR_PTR(-ENODEV);
 
index 2baab6f3861d20ec998266dd0d36e30b3f446262..7fbf0539e14a06d240ef14fa6c1f42098a11f5f2 100644 (file)
@@ -84,10 +84,6 @@ struct backlight_properties {
 
 #define BL_CORE_SUSPENDED      (1 << 0)        /* backlight is suspended */
 #define BL_CORE_FBBLANK                (1 << 1)        /* backlight is under an fb blank event */
-#define BL_CORE_DRIVER4                (1 << 28)       /* reserved for driver specific use */
-#define BL_CORE_DRIVER3                (1 << 29)       /* reserved for driver specific use */
-#define BL_CORE_DRIVER2                (1 << 30)       /* reserved for driver specific use */
-#define BL_CORE_DRIVER1                (1 << 31)       /* reserved for driver specific use */
 
 };
 
index 34cc85864be5e95f4e9442ed48f45a35fb142b3f..ddd0b953323b1051f79635dfa32b7adc210f72fb 100644 (file)
@@ -108,9 +108,9 @@ struct as3711_regulator_pdata {
 };
 
 struct as3711_bl_pdata {
-       const char *su1_fb;
+       bool su1_fb;
        int su1_max_uA;
-       const char *su2_fb;
+       bool su2_fb;
        int su2_max_uA;
        enum as3711_su2_feedback su2_feedback;
        enum as3711_su2_fbprot su2_fbprot;
index 796fb9794c9eb67cb55902697ae3d3b12621e59a..fe0ce7bc59cfa2948ed9ad15d0f7700af8f93d3a 100644 (file)
@@ -21,6 +21,7 @@ enum rave_sp_command {
        RAVE_SP_CMD_STATUS                      = 0xA0,
        RAVE_SP_CMD_SW_WDT                      = 0xA1,
        RAVE_SP_CMD_PET_WDT                     = 0xA2,
+       RAVE_SP_CMD_SET_BACKLIGHT               = 0xA6,
        RAVE_SP_CMD_RESET                       = 0xA7,
        RAVE_SP_CMD_RESET_REASON                = 0xA8,
 
index e8afbd71a140696cd5b6affe1a7fbada5ccc5148..8ea265a022fdb3752476ea1e1e2ef8def054b041 100644 (file)
@@ -14,6 +14,8 @@ struct platform_pwm_backlight_data {
        unsigned int lth_brightness;
        unsigned int pwm_period_ns;
        unsigned int *levels;
+       unsigned int post_pwm_on_delay;
+       unsigned int pwm_off_delay;
        /* TODO remove once all users are switched to gpiod_* API */
        int enable_gpio;
        int (*init)(struct device *dev);