From dde7a4124689b51f7393bfbb8270e8d4e33f8457 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 30 Sep 2022 11:26:47 +0200 Subject: [PATCH] kernel: move ubnt ledbar driver to a separate package Simplifies the tree by removing a non-upstream kernel patch and related kconfig symbols. Signed-off-by: Felix Fietkau --- package/kernel/ubnt-ledbar/Makefile | 34 +++++++++ package/kernel/ubnt-ledbar/src/Makefile | 1 + .../ubnt-ledbar/src}/leds-ubnt-ledbar.c | 73 +++++++++++++++---- target/linux/mediatek/filogic/config-5.15 | 1 - target/linux/mediatek/modules.mk | 16 ---- .../patches-5.15/800-ubnt-ledbar-driver.patch | 29 -------- 6 files changed, 94 insertions(+), 60 deletions(-) create mode 100644 package/kernel/ubnt-ledbar/Makefile create mode 100644 package/kernel/ubnt-ledbar/src/Makefile rename {target/linux/mediatek/files/drivers/leds => package/kernel/ubnt-ledbar/src}/leds-ubnt-ledbar.c (71%) delete mode 100644 target/linux/mediatek/patches-5.15/800-ubnt-ledbar-driver.patch diff --git a/package/kernel/ubnt-ledbar/Makefile b/package/kernel/ubnt-ledbar/Makefile new file mode 100644 index 000000000..90eccf1c2 --- /dev/null +++ b/package/kernel/ubnt-ledbar/Makefile @@ -0,0 +1,34 @@ +# +# Copyright (C) 2008-2010 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_NAME:=ubnt-ledbar +PKG_RELEASE:=1 +PKG_LICENSE:=GPL-2.0 + +include $(INCLUDE_DIR)/package.mk + +define KernelPackage/leds-ubnt-ledbar + SUBMENU:=LED modules + TITLE:=Ubiquiti UniFi 6 LR LED support + FILES:= \ + $(PKG_BUILD_DIR)/leds-ubnt-ledbar.ko + AUTOLOAD:=$(call AutoProbe,leds-ubnt-ledbar,1) + DEPENDS:=+kmod-i2c-core +endef + +define KernelPackage/leds-ubnt-ledbar/description + LED support for some Ubiquiti UniFi access points. +endef + +define Build/Compile + $(KERNEL_MAKE) M="$(PKG_BUILD_DIR)" modules +endef + +$(eval $(call KernelPackage,leds-ubnt-ledbar)) diff --git a/package/kernel/ubnt-ledbar/src/Makefile b/package/kernel/ubnt-ledbar/src/Makefile new file mode 100644 index 000000000..a81d9377c --- /dev/null +++ b/package/kernel/ubnt-ledbar/src/Makefile @@ -0,0 +1 @@ +obj-m := leds-ubnt-ledbar.o diff --git a/target/linux/mediatek/files/drivers/leds/leds-ubnt-ledbar.c b/package/kernel/ubnt-ledbar/src/leds-ubnt-ledbar.c similarity index 71% rename from target/linux/mediatek/files/drivers/leds/leds-ubnt-ledbar.c rename to package/kernel/ubnt-ledbar/src/leds-ubnt-ledbar.c index 9c68d40ee..555340c5e 100644 --- a/target/linux/mediatek/files/drivers/leds/leds-ubnt-ledbar.c +++ b/package/kernel/ubnt-ledbar/src/leds-ubnt-ledbar.c @@ -26,31 +26,35 @@ #define UBNT_LEDBAR_MAX_BRIGHTNESS 0xff #define UBNT_LEDBAR_TRANSACTION_LENGTH 8 -#define UBNT_LEDBAR_TRANSACTION_SUCCESS 0xaa +#define UBNT_LEDBAR_TRANSACTION_SUCCESS (char) 0xaa #define UBNT_LEDBAR_TRANSACTION_BLUE_IDX 2 #define UBNT_LEDBAR_TRANSACTION_GREEN_IDX 3 #define UBNT_LEDBAR_TRANSACTION_RED_IDX 4 +#define UBNT_LEDBAR_TRANSACTION_LED_COUNT_IDX 6 struct ubnt_ledbar { struct mutex lock; + u32 led_count; struct i2c_client *client; struct led_classdev led_red; struct led_classdev led_green; struct led_classdev led_blue; struct gpio_desc *enable_gpio; + struct gpio_desc *reset_gpio; }; -static int ubnt_ledbar_perform_transaction(struct ubnt_ledbar *ledbar, - char *transaction) +static void ubnt_ledbar_perform_transaction(struct ubnt_ledbar *ledbar, + const char *transaction, int len, + char *result, int result_len) { - int ret; int i; - for (i = 0; i < UBNT_LEDBAR_TRANSACTION_LENGTH; i++) + for (i = 0; i < len; i++) i2c_smbus_write_byte(ledbar->client, transaction[i]); - return i2c_smbus_read_byte(ledbar->client); + for (i = 0; i < result_len; i++) + result[i] = i2c_smbus_read_byte(ledbar->client); } static int ubnt_ledbar_apply_state(struct ubnt_ledbar *ledbar) @@ -58,7 +62,7 @@ static int ubnt_ledbar_apply_state(struct ubnt_ledbar *ledbar) char setup_msg[UBNT_LEDBAR_TRANSACTION_LENGTH] = {0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11}; char led_msg[UBNT_LEDBAR_TRANSACTION_LENGTH] = {0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x00}; + 0x00, 0x00, 0x00, 0x00}; char i2c_response; int ret = 0; @@ -67,34 +71,63 @@ static int ubnt_ledbar_apply_state(struct ubnt_ledbar *ledbar) led_msg[UBNT_LEDBAR_TRANSACTION_BLUE_IDX] = ledbar->led_blue.brightness; led_msg[UBNT_LEDBAR_TRANSACTION_GREEN_IDX] = ledbar->led_green.brightness; led_msg[UBNT_LEDBAR_TRANSACTION_RED_IDX] = ledbar->led_red.brightness; + led_msg[UBNT_LEDBAR_TRANSACTION_LED_COUNT_IDX] = ledbar->led_count; - gpiod_set_raw_value(ledbar->enable_gpio, 1); + gpiod_set_value(ledbar->enable_gpio, 1); msleep(10); - i2c_response = ubnt_ledbar_perform_transaction(ledbar, setup_msg); + ubnt_ledbar_perform_transaction(ledbar, setup_msg, sizeof(setup_msg), &i2c_response, sizeof(i2c_response)); if (i2c_response != UBNT_LEDBAR_TRANSACTION_SUCCESS) { - dev_err(&ledbar->client->dev, "Error initializing LED transaction: %02x\n", ret); + dev_err(&ledbar->client->dev, "Error initializing LED transaction: %02hhx\n", i2c_response); ret = -EINVAL; goto out_gpio; } - i2c_response = ubnt_ledbar_perform_transaction(ledbar, led_msg); + ubnt_ledbar_perform_transaction(ledbar, led_msg, sizeof(led_msg), &i2c_response, sizeof(i2c_response)); if (i2c_response != UBNT_LEDBAR_TRANSACTION_SUCCESS) { - dev_err(&ledbar->client->dev, "Failed LED transaction: %02x\n", ret); + dev_err(&ledbar->client->dev, "Failed LED transaction: %02hhx\n", i2c_response); ret = -EINVAL; goto out_gpio; } msleep(10); out_gpio: - gpiod_set_raw_value(ledbar->enable_gpio, 0); + gpiod_set_value(ledbar->enable_gpio, 0); mutex_unlock(&ledbar->lock); return ret; } +static void ubnt_ledbar_reset(struct ubnt_ledbar *ledbar) +{ + static const char init_msg[16] = {0x02, 0x81, 0xfd, 0x7e, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00}; + char init_response[4]; + + if (!ledbar->reset_gpio) + return; + + mutex_lock(&ledbar->lock); + + gpiod_set_value(ledbar->reset_gpio, 1); + msleep(10); + gpiod_set_value(ledbar->reset_gpio, 0); + + msleep(10); + + gpiod_set_value(ledbar->enable_gpio, 1); + msleep(10); + ubnt_ledbar_perform_transaction(ledbar, init_msg, sizeof(init_msg), init_response, sizeof(init_response)); + msleep(10); + gpiod_set_value(ledbar->enable_gpio, 0); + + mutex_unlock(&ledbar->lock); +} + #define UBNT_LEDBAR_CONTROL_RGBS(name) \ static int ubnt_ledbar_set_##name##_brightness(struct led_classdev *led_cdev,\ enum led_brightness value) \ @@ -153,7 +186,16 @@ static int ubnt_ledbar_probe(struct i2c_client *client, return ret; } - gpiod_direction_output(ledbar->enable_gpio, 0); + ledbar->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_LOW); + + if (IS_ERR(ledbar->reset_gpio)) { + ret = PTR_ERR(ledbar->reset_gpio); + dev_err(&client->dev, "Failed to get reset gpio: %d\n", ret); + return ret; + } + + ledbar->led_count = 1; + of_property_read_u32(np, "led-count", &ledbar->led_count); ledbar->client = client; @@ -161,6 +203,9 @@ static int ubnt_ledbar_probe(struct i2c_client *client, i2c_set_clientdata(client, ledbar); + // Reset and initialize the MCU + ubnt_ledbar_reset(ledbar); + ledbar->led_red.brightness_set_blocking = ubnt_ledbar_set_red_brightness; ubnt_ledbar_init_led(of_get_child_by_name(np, "red"), ledbar, &ledbar->led_red); diff --git a/target/linux/mediatek/filogic/config-5.15 b/target/linux/mediatek/filogic/config-5.15 index 963815b26..558894e5e 100644 --- a/target/linux/mediatek/filogic/config-5.15 +++ b/target/linux/mediatek/filogic/config-5.15 @@ -197,7 +197,6 @@ CONFIG_IRQ_TIME_ACCOUNTING=y CONFIG_IRQ_WORK=y CONFIG_JBD2=y CONFIG_JUMP_LABEL=y -# CONFIG_LEDS_UBNT_LEDBAR is not set CONFIG_LIBFDT=y CONFIG_LOCK_DEBUGGING_SUPPORT=y CONFIG_LOCK_SPIN_ON_OWNER=y diff --git a/target/linux/mediatek/modules.mk b/target/linux/mediatek/modules.mk index 0eb2866cf..467934256 100644 --- a/target/linux/mediatek/modules.mk +++ b/target/linux/mediatek/modules.mk @@ -38,19 +38,3 @@ define KernelPackage/sdhci-mtk endef $(eval $(call KernelPackage,sdhci-mtk)) - -define KernelPackage/leds-ubnt-ledbar - SUBMENU:=LED modules - TITLE:=Ubiquiti UniFi 6 LR LED support - KCONFIG:=CONFIG_LEDS_UBNT_LEDBAR - FILES:= \ - $(LINUX_DIR)/drivers/leds/leds-ubnt-ledbar.ko - AUTOLOAD:=$(call AutoProbe,leds-ubnt-ledbar,1) - DEPENDS:=@TARGET_mediatek_mt7622 +kmod-i2c-core -endef - -define KernelPackage/leds-ubnt-ledbar/description - LED support for Ubiquiti UniFi 6 LR -endef - -$(eval $(call KernelPackage,leds-ubnt-ledbar)) diff --git a/target/linux/mediatek/patches-5.15/800-ubnt-ledbar-driver.patch b/target/linux/mediatek/patches-5.15/800-ubnt-ledbar-driver.patch deleted file mode 100644 index 146e6ae2f..000000000 --- a/target/linux/mediatek/patches-5.15/800-ubnt-ledbar-driver.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- a/drivers/leds/Kconfig -+++ b/drivers/leds/Kconfig -@@ -876,6 +876,16 @@ source "drivers/leds/blink/Kconfig" - comment "Flash and Torch LED drivers" - source "drivers/leds/flash/Kconfig" - -+config LEDS_UBNT_LEDBAR -+ tristate "LED support for Ubiquiti UniFi 6 LR" -+ depends on LEDS_CLASS && I2C && OF -+ help -+ This option enables support for the Ubiquiti LEDBAR -+ LED driver. -+ -+ To compile this driver as a module, choose M here: the module -+ will be called leds-ubnt-ledbar. -+ - comment "LED Triggers" - source "drivers/leds/trigger/Kconfig" - ---- a/drivers/leds/Makefile -+++ b/drivers/leds/Makefile -@@ -87,6 +87,7 @@ obj-$(CONFIG_LEDS_TURRIS_OMNIA) += leds - obj-$(CONFIG_LEDS_WM831X_STATUS) += leds-wm831x-status.o - obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o - obj-$(CONFIG_LEDS_WRAP) += leds-wrap.o -+obj-$(CONFIG_LEDS_UBNT_LEDBAR) += leds-ubnt-ledbar.o - - # LED SPI Drivers - obj-$(CONFIG_LEDS_CR0014114) += leds-cr0014114.o