Commit 1368d06d authored by Duje Mihanović's avatar Duje Mihanović Committed by Lee Jones
Browse files

leds: Introduce ExpressWire library



The ExpressWire protocol is shared between at least KTD2692 and KTD2801
with slight differences such as timings and the former not having a
defined set of pulses for enabling the protocol (possibly because it
does not support PWM unlike KTD2801). Despite these differences the
ExpressWire handling code can be shared between the two, so in
preparation for adding KTD2801 support introduce a library implementing
this protocol.

Suggested-by: default avatarDaniel Thompson <daniel.thompson@linaro.org>
Reviewed-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Reviewed-by: default avatarDaniel Thompson <daniel.thompson@linaro.org>
Signed-off-by: default avatarDuje Mihanović <duje.mihanovic@skole.hr>
Link: https://lore.kernel.org/r/20240125-ktd2801-v5-1-e22da232a825@skole.hr


Signed-off-by: default avatarLee Jones <lee@kernel.org>
parent 6613476e
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -7979,6 +7979,13 @@ S: Maintained
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/linkinjeon/exfat.git
F:	fs/exfat/
EXPRESSWIRE PROTOCOL LIBRARY
M:	Duje Mihanović <duje.mihanovic@skole.hr>
L:	linux-leds@vger.kernel.org
S:	Maintained
F:	drivers/leds/leds-expresswire.c
F:	include/linux/leds-expresswire.h
EXT2 FILE SYSTEM
M:	Jan Kara <jack@suse.com>
L:	linux-ext4@vger.kernel.org
+4 −0
Original line number Diff line number Diff line
@@ -186,6 +186,10 @@ config LEDS_EL15203000
	  To compile this driver as a module, choose M here: the module
	  will be called leds-el15203000.

config LEDS_EXPRESSWIRE
	bool
	depends on GPIOLIB

config LEDS_TURRIS_OMNIA
	tristate "LED support for CZ.NIC's Turris Omnia"
	depends on LEDS_CLASS_MULTICOLOR
+3 −0
Original line number Diff line number Diff line
@@ -91,6 +91,9 @@ obj-$(CONFIG_LEDS_WM831X_STATUS) += leds-wm831x-status.o
obj-$(CONFIG_LEDS_WM8350)		+= leds-wm8350.o
obj-$(CONFIG_LEDS_WRAP)			+= leds-wrap.o

# Kinetic ExpressWire Protocol
obj-$(CONFIG_LEDS_EXPRESSWIRE)		+= leds-expresswire.o

# LED SPI Drivers
obj-$(CONFIG_LEDS_CR0014114)		+= leds-cr0014114.o
obj-$(CONFIG_LEDS_DAC124S085)		+= leds-dac124s085.o
+68 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Shared library for Kinetic's ExpressWire protocol.
 * This protocol works by pulsing the ExpressWire IC's control GPIO.
 * ktd2692 and ktd2801 are known to use this protocol.
 */

#include <linux/delay.h>
#include <linux/gpio/consumer.h>
#include <linux/leds-expresswire.h>

void expresswire_power_off(struct expresswire_common_props *props)
{
	gpiod_set_value_cansleep(props->ctrl_gpio, 0);
	usleep_range(props->timing.poweroff_us, props->timing.poweroff_us * 2);
}
EXPORT_SYMBOL_NS_GPL(expresswire_power_off, EXPRESSWIRE);

void expresswire_enable(struct expresswire_common_props *props)
{
	gpiod_set_value(props->ctrl_gpio, 1);
	udelay(props->timing.detect_delay_us);
	gpiod_set_value(props->ctrl_gpio, 0);
	udelay(props->timing.detect_us);
	gpiod_set_value(props->ctrl_gpio, 1);
}
EXPORT_SYMBOL_NS_GPL(expresswire_enable, EXPRESSWIRE);

void expresswire_start(struct expresswire_common_props *props)
{
	gpiod_set_value(props->ctrl_gpio, 1);
	udelay(props->timing.data_start_us);
}
EXPORT_SYMBOL_NS_GPL(expresswire_start, EXPRESSWIRE);

void expresswire_end(struct expresswire_common_props *props)
{
	gpiod_set_value(props->ctrl_gpio, 0);
	udelay(props->timing.end_of_data_low_us);
	gpiod_set_value(props->ctrl_gpio, 1);
	udelay(props->timing.end_of_data_high_us);
}
EXPORT_SYMBOL_NS_GPL(expresswire_end, EXPRESSWIRE);

void expresswire_set_bit(struct expresswire_common_props *props, bool bit)
{
	if (bit) {
		gpiod_set_value(props->ctrl_gpio, 0);
		udelay(props->timing.short_bitset_us);
		gpiod_set_value(props->ctrl_gpio, 1);
		udelay(props->timing.long_bitset_us);
	} else {
		gpiod_set_value(props->ctrl_gpio, 0);
		udelay(props->timing.long_bitset_us);
		gpiod_set_value(props->ctrl_gpio, 1);
		udelay(props->timing.short_bitset_us);
	}
}
EXPORT_SYMBOL_NS_GPL(expresswire_set_bit, EXPRESSWIRE);

void expresswire_write_u8(struct expresswire_common_props *props, u8 val)
{
	expresswire_start(props);
	for (int i = 7; i >= 0; i--)
		expresswire_set_bit(props, val & BIT(i));
	expresswire_end(props);
}
EXPORT_SYMBOL_NS_GPL(expresswire_write_u8, EXPRESSWIRE);
+36 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Shared library for Kinetic's ExpressWire protocol.
 * This protocol works by pulsing the ExpressWire IC's control GPIO.
 * ktd2692 and ktd2801 are known to use this protocol.
 */

#ifndef _LEDS_EXPRESSWIRE_H
#define _LEDS_EXPRESSWIRE_H

#include <linux/gpio/consumer.h>

struct expresswire_timing {
	unsigned long poweroff_us;
	unsigned long detect_delay_us;
	unsigned long detect_us;
	unsigned long data_start_us;
	unsigned long end_of_data_low_us;
	unsigned long end_of_data_high_us;
	unsigned long short_bitset_us;
	unsigned long long_bitset_us;
};

struct expresswire_common_props {
	struct gpio_desc *ctrl_gpio;
	struct expresswire_timing timing;
};

void expresswire_power_off(struct expresswire_common_props *props);
void expresswire_enable(struct expresswire_common_props *props);
void expresswire_start(struct expresswire_common_props *props);
void expresswire_end(struct expresswire_common_props *props);
void expresswire_set_bit(struct expresswire_common_props *props, bool bit);
void expresswire_write_u8(struct expresswire_common_props *props, u8 val);

#endif /* _LEDS_EXPRESSWIRE_H */