···11+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)22+%YAML 1.233+---44+$id: http://devicetree.org/schemas/leds/backlight/kinetic,ktd2801.yaml#55+$schema: http://devicetree.org/meta-schemas/core.yaml#66+77+title: Kinetic Technologies KTD2801 one-wire backlight88+99+maintainers:1010+ - Duje Mihanović <duje.mihanovic@skole.hr>1111+1212+description: |1313+ The Kinetic Technologies KTD2801 is a LED backlight driver controlled1414+ by a single GPIO line. The driver can be controlled with a PWM signal1515+ or by pulsing the GPIO line to set the backlight level. This is called1616+ "ExpressWire".1717+1818+allOf:1919+ - $ref: common.yaml#2020+2121+properties:2222+ compatible:2323+ const: kinetic,ktd28012424+2525+ ctrl-gpios:2626+ maxItems: 12727+2828+ default-brightness: true2929+ max-brightness: true3030+3131+required:3232+ - compatible3333+ - ctrl-gpios3434+3535+additionalProperties: false3636+3737+examples:3838+ - |3939+ #include <dt-bindings/gpio/gpio.h>4040+4141+ backlight {4242+ compatible = "kinetic,ktd2801";4343+ ctrl-gpios = <&gpio 97 GPIO_ACTIVE_HIGH>;4444+ max-brightness = <210>;4545+ default-brightness = <100>;4646+ };
+13
MAINTAINERS
···79797979T: git git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/exfat.git79807980F: fs/exfat/7981798179827982+EXPRESSWIRE PROTOCOL LIBRARY79837983+M: Duje Mihanović <duje.mihanovic@skole.hr>79847984+L: linux-leds@vger.kernel.org79857985+S: Maintained79867986+F: drivers/leds/leds-expresswire.c79877987+F: include/linux/leds-expresswire.h79887988+79827989EXT2 FILE SYSTEM79837990M: Jan Kara <jack@suse.com>79847991L: linux-ext4@vger.kernel.org···1205112044S: Maintained1205212045F: Documentation/devicetree/bindings/leds/backlight/kinetic,ktd253.yaml1205312046F: drivers/video/backlight/ktd253-backlight.c1204712047+1204812048+KTD2801 BACKLIGHT DRIVER1204912049+M: Duje Mihanović <duje.mihanovic@skole.hr>1205012050+S: Maintained1205112051+F: Documentation/devicetree/bindings/leds/backlight/kinetic,ktd2801.yaml1205212052+F: drivers/video/backlight/ktd2801-backlight.c12054120531205512054KTEST1205612055M: Steven Rostedt <rostedt@goodmis.org>
+4
drivers/leds/Kconfig
···186186 To compile this driver as a module, choose M here: the module187187 will be called leds-el15203000.188188189189+config LEDS_EXPRESSWIRE190190+ bool191191+ depends on GPIOLIB192192+189193config LEDS_TURRIS_OMNIA190194 tristate "LED support for CZ.NIC's Turris Omnia"191195 depends on LEDS_CLASS_MULTICOLOR
···2323config LEDS_KTD26922424 tristate "LED support for Kinetic KTD2692 flash LED controller"2525 depends on OF2626- depends on GPIOLIB || COMPILE_TEST2626+ depends on GPIOLIB2727+ select LEDS_EXPRESSWIRE2728 help2829 This option enables support for Kinetic KTD2692 LED flash connected2930 through ExpressWire interface.
+27-89
drivers/leds/flash/leds-ktd2692.c
···66 * Ingi Kim <ingi2.kim@samsung.com>77 */8899-#include <linux/delay.h>109#include <linux/err.h>1110#include <linux/gpio/consumer.h>1111+#include <linux/leds-expresswire.h>1212#include <linux/led-class-flash.h>1313#include <linux/module.h>1414#include <linux/mutex.h>···3737#define KTD2692_REG_FLASH_CURRENT_BASE 0x803838#define KTD2692_REG_MODE_BASE 0xA039394040-/* Set bit coding time for expresswire interface */4141-#define KTD2692_TIME_RESET_US 7004242-#define KTD2692_TIME_DATA_START_TIME_US 104343-#define KTD2692_TIME_HIGH_END_OF_DATA_US 3504444-#define KTD2692_TIME_LOW_END_OF_DATA_US 104545-#define KTD2692_TIME_SHORT_BITSET_US 44646-#define KTD2692_TIME_LONG_BITSET_US 124747-4840/* KTD2692 default length of name */4941#define KTD2692_NAME_LENGTH 205050-5151-enum ktd2692_bitset {5252- KTD2692_LOW = 0,5353- KTD2692_HIGH,5454-};55425643/* Movie / Flash Mode Control */5744enum ktd2692_led_mode {···5871 enum led_brightness max_brightness;5972};60737474+const struct expresswire_timing ktd2692_timing = {7575+ .poweroff_us = 700,7676+ .data_start_us = 10,7777+ .end_of_data_low_us = 10,7878+ .end_of_data_high_us = 350,7979+ .short_bitset_us = 4,8080+ .long_bitset_us = 128181+};8282+6183struct ktd2692_context {8484+ /* Common ExpressWire properties (ctrl GPIO and timing) */8585+ struct expresswire_common_props props;8686+6287 /* Related LED Flash class device */6388 struct led_classdev_flash fled_cdev;6489···7980 struct regulator *regulator;80818182 struct gpio_desc *aux_gpio;8282- struct gpio_desc *ctrl_gpio;83838484 enum ktd2692_led_mode mode;8585 enum led_brightness torch_brightness;···8890 struct led_classdev_flash *fled_cdev)8991{9092 return container_of(fled_cdev, struct ktd2692_context, fled_cdev);9191-}9292-9393-static void ktd2692_expresswire_start(struct ktd2692_context *led)9494-{9595- gpiod_direction_output(led->ctrl_gpio, KTD2692_HIGH);9696- udelay(KTD2692_TIME_DATA_START_TIME_US);9797-}9898-9999-static void ktd2692_expresswire_reset(struct ktd2692_context *led)100100-{101101- gpiod_direction_output(led->ctrl_gpio, KTD2692_LOW);102102- udelay(KTD2692_TIME_RESET_US);103103-}104104-105105-static void ktd2692_expresswire_end(struct ktd2692_context *led)106106-{107107- gpiod_direction_output(led->ctrl_gpio, KTD2692_LOW);108108- udelay(KTD2692_TIME_LOW_END_OF_DATA_US);109109- gpiod_direction_output(led->ctrl_gpio, KTD2692_HIGH);110110- udelay(KTD2692_TIME_HIGH_END_OF_DATA_US);111111-}112112-113113-static void ktd2692_expresswire_set_bit(struct ktd2692_context *led, bool bit)114114-{115115- /*116116- * The Low Bit(0) and High Bit(1) is based on a time detection117117- * algorithm between time low and time high118118- * Time_(L_LB) : Low time of the Low Bit(0)119119- * Time_(H_LB) : High time of the LOW Bit(0)120120- * Time_(L_HB) : Low time of the High Bit(1)121121- * Time_(H_HB) : High time of the High Bit(1)122122- *123123- * It can be simplified to:124124- * Low Bit(0) : 2 * Time_(H_LB) < Time_(L_LB)125125- * High Bit(1) : 2 * Time_(L_HB) < Time_(H_HB)126126- * HIGH ___ ____ _.. _________ ___127127- * |_________| |_.. |____| |__|128128- * LOW <L_LB> <H_LB> <L_HB> <H_HB>129129- * [ Low Bit (0) ] [ High Bit(1) ]130130- */131131- if (bit) {132132- gpiod_direction_output(led->ctrl_gpio, KTD2692_LOW);133133- udelay(KTD2692_TIME_SHORT_BITSET_US);134134- gpiod_direction_output(led->ctrl_gpio, KTD2692_HIGH);135135- udelay(KTD2692_TIME_LONG_BITSET_US);136136- } else {137137- gpiod_direction_output(led->ctrl_gpio, KTD2692_LOW);138138- udelay(KTD2692_TIME_LONG_BITSET_US);139139- gpiod_direction_output(led->ctrl_gpio, KTD2692_HIGH);140140- udelay(KTD2692_TIME_SHORT_BITSET_US);141141- }142142-}143143-144144-static void ktd2692_expresswire_write(struct ktd2692_context *led, u8 value)145145-{146146- int i;147147-148148- ktd2692_expresswire_start(led);149149- for (i = 7; i >= 0; i--)150150- ktd2692_expresswire_set_bit(led, value & BIT(i));151151- ktd2692_expresswire_end(led);15293}1539415495static int ktd2692_led_brightness_set(struct led_classdev *led_cdev,···100163101164 if (brightness == LED_OFF) {102165 led->mode = KTD2692_MODE_DISABLE;103103- gpiod_direction_output(led->aux_gpio, KTD2692_LOW);166166+ gpiod_direction_output(led->aux_gpio, 0);104167 } else {105105- ktd2692_expresswire_write(led, brightness |168168+ expresswire_write_u8(&led->props, brightness |106169 KTD2692_REG_MOVIE_CURRENT_BASE);107170 led->mode = KTD2692_MODE_MOVIE;108171 }109172110110- ktd2692_expresswire_write(led, led->mode | KTD2692_REG_MODE_BASE);173173+ expresswire_write_u8(&led->props, led->mode | KTD2692_REG_MODE_BASE);111174 mutex_unlock(&led->lock);112175113176 return 0;···124187125188 if (state) {126189 flash_tm_reg = GET_TIMEOUT_OFFSET(timeout->val, timeout->step);127127- ktd2692_expresswire_write(led, flash_tm_reg190190+ expresswire_write_u8(&led->props, flash_tm_reg128191 | KTD2692_REG_FLASH_TIMEOUT_BASE);129192130193 led->mode = KTD2692_MODE_FLASH;131131- gpiod_direction_output(led->aux_gpio, KTD2692_HIGH);194194+ gpiod_direction_output(led->aux_gpio, 1);132195 } else {133196 led->mode = KTD2692_MODE_DISABLE;134134- gpiod_direction_output(led->aux_gpio, KTD2692_LOW);197197+ gpiod_direction_output(led->aux_gpio, 0);135198 }136199137137- ktd2692_expresswire_write(led, led->mode | KTD2692_REG_MODE_BASE);200200+ expresswire_write_u8(&led->props, led->mode | KTD2692_REG_MODE_BASE);138201139202 fled_cdev->led_cdev.brightness = LED_OFF;140203 led->mode = KTD2692_MODE_DISABLE;···184247static void ktd2692_setup(struct ktd2692_context *led)185248{186249 led->mode = KTD2692_MODE_DISABLE;187187- ktd2692_expresswire_reset(led);188188- gpiod_direction_output(led->aux_gpio, KTD2692_LOW);250250+ expresswire_power_off(&led->props);251251+ gpiod_direction_output(led->aux_gpio, 0);189252190190- ktd2692_expresswire_write(led, (KTD2692_MM_MIN_CURR_THRESHOLD_SCALE - 1)253253+ expresswire_write_u8(&led->props, (KTD2692_MM_MIN_CURR_THRESHOLD_SCALE - 1)191254 | KTD2692_REG_MM_MIN_CURR_THRESHOLD_BASE);192192- ktd2692_expresswire_write(led, KTD2692_FLASH_MODE_CURR_PERCENT(45)255255+ expresswire_write_u8(&led->props, KTD2692_FLASH_MODE_CURR_PERCENT(45)193256 | KTD2692_REG_FLASH_CURRENT_BASE);194257}195258···214277 if (!np)215278 return -ENXIO;216279217217- led->ctrl_gpio = devm_gpiod_get(dev, "ctrl", GPIOD_ASIS);218218- ret = PTR_ERR_OR_ZERO(led->ctrl_gpio);280280+ led->props.ctrl_gpio = devm_gpiod_get(dev, "ctrl", GPIOD_ASIS);281281+ ret = PTR_ERR_OR_ZERO(led->props.ctrl_gpio);219282 if (ret)220283 return dev_err_probe(dev, ret, "cannot get ctrl-gpios\n");221284···349412350413module_platform_driver(ktd2692_driver);351414415415+MODULE_IMPORT_NS(EXPRESSWIRE);352416MODULE_AUTHOR("Ingi Kim <ingi2.kim@samsung.com>");353417MODULE_DESCRIPTION("Kinetic KTD2692 LED driver");354418MODULE_LICENSE("GPL v2");
+72
drivers/leds/leds-expresswire.c
···11+// SPDX-License-Identifier: GPL-2.0-only22+/*33+ * Shared library for Kinetic's ExpressWire protocol.44+ * This protocol works by pulsing the ExpressWire IC's control GPIO.55+ * ktd2692 and ktd2801 are known to use this protocol.66+ */77+88+#include <linux/bits.h>99+#include <linux/delay.h>1010+#include <linux/export.h>1111+#include <linux/gpio/consumer.h>1212+#include <linux/types.h>1313+1414+#include <linux/leds-expresswire.h>1515+1616+void expresswire_power_off(struct expresswire_common_props *props)1717+{1818+ gpiod_set_value_cansleep(props->ctrl_gpio, 0);1919+ usleep_range(props->timing.poweroff_us, props->timing.poweroff_us * 2);2020+}2121+EXPORT_SYMBOL_NS_GPL(expresswire_power_off, EXPRESSWIRE);2222+2323+void expresswire_enable(struct expresswire_common_props *props)2424+{2525+ gpiod_set_value(props->ctrl_gpio, 1);2626+ udelay(props->timing.detect_delay_us);2727+ gpiod_set_value(props->ctrl_gpio, 0);2828+ udelay(props->timing.detect_us);2929+ gpiod_set_value(props->ctrl_gpio, 1);3030+}3131+EXPORT_SYMBOL_NS_GPL(expresswire_enable, EXPRESSWIRE);3232+3333+void expresswire_start(struct expresswire_common_props *props)3434+{3535+ gpiod_set_value(props->ctrl_gpio, 1);3636+ udelay(props->timing.data_start_us);3737+}3838+EXPORT_SYMBOL_NS_GPL(expresswire_start, EXPRESSWIRE);3939+4040+void expresswire_end(struct expresswire_common_props *props)4141+{4242+ gpiod_set_value(props->ctrl_gpio, 0);4343+ udelay(props->timing.end_of_data_low_us);4444+ gpiod_set_value(props->ctrl_gpio, 1);4545+ udelay(props->timing.end_of_data_high_us);4646+}4747+EXPORT_SYMBOL_NS_GPL(expresswire_end, EXPRESSWIRE);4848+4949+void expresswire_set_bit(struct expresswire_common_props *props, bool bit)5050+{5151+ if (bit) {5252+ gpiod_set_value(props->ctrl_gpio, 0);5353+ udelay(props->timing.short_bitset_us);5454+ gpiod_set_value(props->ctrl_gpio, 1);5555+ udelay(props->timing.long_bitset_us);5656+ } else {5757+ gpiod_set_value(props->ctrl_gpio, 0);5858+ udelay(props->timing.long_bitset_us);5959+ gpiod_set_value(props->ctrl_gpio, 1);6060+ udelay(props->timing.short_bitset_us);6161+ }6262+}6363+EXPORT_SYMBOL_NS_GPL(expresswire_set_bit, EXPRESSWIRE);6464+6565+void expresswire_write_u8(struct expresswire_common_props *props, u8 val)6666+{6767+ expresswire_start(props);6868+ for (int i = 7; i >= 0; i--)6969+ expresswire_set_bit(props, val & BIT(i));7070+ expresswire_end(props);7171+}7272+EXPORT_SYMBOL_NS_GPL(expresswire_write_u8, EXPRESSWIRE);
+7
drivers/video/backlight/Kconfig
···183183 which is a 1-wire GPIO-controlled backlight found in some mobile184184 phones.185185186186+config BACKLIGHT_KTD2801187187+ tristate "Backlight Driver for Kinetic KTD2801"188188+ select LEDS_EXPRESSWIRE189189+ help190190+ Say Y to enable the backlight driver for the Kinetic KTD2801 1-wire191191+ GPIO-controlled backlight found in Samsung Galaxy Core Prime VE LTE.192192+186193config BACKLIGHT_KTZ8866187194 tristate "Backlight Driver for Kinetic KTZ8866"188195 depends on I2C
···11+/* SPDX-License-Identifier: GPL-2.0-only */22+/*33+ * Shared library for Kinetic's ExpressWire protocol.44+ * This protocol works by pulsing the ExpressWire IC's control GPIO.55+ * ktd2692 and ktd2801 are known to use this protocol.66+ */77+88+#ifndef _LEDS_EXPRESSWIRE_H99+#define _LEDS_EXPRESSWIRE_H1010+1111+#include <linux/types.h>1212+1313+struct gpio_desc;1414+1515+struct expresswire_timing {1616+ unsigned long poweroff_us;1717+ unsigned long detect_delay_us;1818+ unsigned long detect_us;1919+ unsigned long data_start_us;2020+ unsigned long end_of_data_low_us;2121+ unsigned long end_of_data_high_us;2222+ unsigned long short_bitset_us;2323+ unsigned long long_bitset_us;2424+};2525+2626+struct expresswire_common_props {2727+ struct gpio_desc *ctrl_gpio;2828+ struct expresswire_timing timing;2929+};3030+3131+void expresswire_power_off(struct expresswire_common_props *props);3232+void expresswire_enable(struct expresswire_common_props *props);3333+void expresswire_start(struct expresswire_common_props *props);3434+void expresswire_end(struct expresswire_common_props *props);3535+void expresswire_set_bit(struct expresswire_common_props *props, bool bit);3636+void expresswire_write_u8(struct expresswire_common_props *props, u8 val);3737+3838+#endif /* _LEDS_EXPRESSWIRE_H */