diff --git a/root/target/linux/ipq40xx/base-files/bin/board_track b/root/target/linux/ipq40xx/base-files/bin/board_track new file mode 100755 index 00000000..651be120 --- /dev/null +++ b/root/target/linux/ipq40xx/base-files/bin/board_track @@ -0,0 +1,41 @@ +#!/bin/sh + +. /lib/functions/uci-defaults.sh + +CFG=/etc/board.json +SLP=30 + +check_modem() { + json_select "$2" + json_get_vars id + + [ -z "$id" ] && { + json_select .. + return 0 + } + + logger -t "board-track" "ls -d /sys/bus/usb/devices/$id/${id}*/tty?*" + ttys=$(ls -d /sys/bus/usb/devices/$id/${id}*/tty?*) + + [ -n "$ttys" ] || { #FAILED TO FIND MODEM + logger -t "board-track" "modem $id not detected" + for m in /sys/class/gpio/modem*_power; do + label="$(basename $m | awk -F_ '{print $1}')" + mctl -s -m ${label} + sleep 1 + mctl -p -m ${label} + done + json_select .. + return 1 + } + + #MODEM UP + json_select .. +} + +board_config_update +while true; do + json_for_each_item check_modem modems + sleep $SLP + [ $SLP -lt 300 ] && SLP=$((SLP+30)) +done diff --git a/root/target/linux/ipq40xx/base-files/etc/init.d/modem_tracker b/root/target/linux/ipq40xx/base-files/etc/init.d/modem_tracker new file mode 100755 index 00000000..9c68c55a --- /dev/null +++ b/root/target/linux/ipq40xx/base-files/etc/init.d/modem_tracker @@ -0,0 +1,33 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2021 Teltonika Networks + +START=96 + +USE_PROCD=1 + +PROG=/bin/board_track +NAME=board_track +PIDCOUNT=1 + +start_service() { + local pid_file="/var/run/${NAME}.${PIDCOUNT}.pid" + + procd_open_instance + procd_set_param command "$PROG" + procd_set_param file /etc/config/system + + procd_set_param respawn + + procd_set_param stdout 1 + procd_set_param pidfile $pid_file + procd_close_instance +} + +reload_service() { + stop + start +} + +service_triggers() { + procd_add_reload_trigger "system" +} diff --git a/root/target/linux/ipq40xx/patches-5.4/100-GPIO-add-named-gpio-exports.patch b/root/target/linux/ipq40xx/patches-5.4/100-GPIO-add-named-gpio-exports.patch new file mode 100644 index 00000000..805836fc --- /dev/null +++ b/root/target/linux/ipq40xx/patches-5.4/100-GPIO-add-named-gpio-exports.patch @@ -0,0 +1,165 @@ +From 4267880319bc1a2270d352e0ded6d6386242a7ef Mon Sep 17 00:00:00 2001 +From: John Crispin +Date: Tue, 12 Aug 2014 20:49:27 +0200 +Subject: [PATCH 24/53] GPIO: add named gpio exports + +Signed-off-by: John Crispin +--- + drivers/gpio/gpiolib-of.c | 68 +++++++++++++++++++++++++++++++++++++++++ + drivers/gpio/gpiolib-sysfs.c | 10 +++++- + include/asm-generic/gpio.h | 6 ++++ + include/linux/gpio/consumer.h | 8 +++++ + 4 files changed, 91 insertions(+), 1 deletion(-) + +--- a/drivers/gpio/gpiolib-of.c ++++ b/drivers/gpio/gpiolib-of.c +@@ -19,6 +19,8 @@ + #include + #include + #include ++#include ++#include + + #include "gpiolib.h" + #include "gpiolib-of.h" +@@ -915,3 +917,68 @@ void of_gpiochip_remove(struct gpio_chip + { + of_node_put(chip->of_node); + } ++ ++static struct of_device_id gpio_export_ids[] = { ++ { .compatible = "gpio-export" }, ++ { /* sentinel */ } ++}; ++ ++static int of_gpio_export_probe(struct platform_device *pdev) ++{ ++ struct device_node *np = pdev->dev.of_node; ++ struct device_node *cnp; ++ u32 val; ++ int nb = 0; ++ ++ for_each_child_of_node(np, cnp) { ++ const char *name = NULL; ++ int gpio; ++ bool dmc; ++ int max_gpio = 1; ++ int i; ++ ++ of_property_read_string(cnp, "gpio-export,name", &name); ++ ++ if (!name) ++ max_gpio = of_gpio_count(cnp); ++ ++ for (i = 0; i < max_gpio; i++) { ++ unsigned flags = 0; ++ enum of_gpio_flags of_flags; ++ ++ gpio = of_get_gpio_flags(cnp, i, &of_flags); ++ if (!gpio_is_valid(gpio)) ++ return gpio; ++ ++ if (of_flags == OF_GPIO_ACTIVE_LOW) ++ flags |= GPIOF_ACTIVE_LOW; ++ ++ if (!of_property_read_u32(cnp, "gpio-export,output", &val)) ++ flags |= val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; ++ else ++ flags |= GPIOF_IN; ++ ++ if (devm_gpio_request_one(&pdev->dev, gpio, flags, name ? name : of_node_full_name(np))) ++ continue; ++ ++ dmc = of_property_read_bool(cnp, "gpio-export,direction_may_change"); ++ gpio_export_with_name(gpio, dmc, name); ++ nb++; ++ } ++ } ++ ++ dev_info(&pdev->dev, "%d gpio(s) exported\n", nb); ++ ++ return 0; ++} ++ ++static struct platform_driver gpio_export_driver = { ++ .driver = { ++ .name = "gpio-export", ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(gpio_export_ids), ++ }, ++ .probe = of_gpio_export_probe, ++}; ++ ++module_platform_driver(gpio_export_driver); +--- a/drivers/gpio/gpiolib-sysfs.c ++++ b/drivers/gpio/gpiolib-sysfs.c +@@ -571,7 +571,7 @@ static struct class gpio_class = { + * + * Returns zero on success, else an error. + */ +-int gpiod_export(struct gpio_desc *desc, bool direction_may_change) ++int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name) + { + struct gpio_chip *chip; + struct gpio_device *gdev; +@@ -633,6 +633,8 @@ int gpiod_export(struct gpio_desc *desc, + offset = gpio_chip_hwgpio(desc); + if (chip->names && chip->names[offset]) + ioname = chip->names[offset]; ++ if (name) ++ ioname = name; + + dev = device_create_with_groups(&gpio_class, &gdev->dev, + MKDEV(0, 0), data, gpio_groups, +@@ -654,6 +656,12 @@ err_unlock: + gpiod_dbg(desc, "%s: status %d\n", __func__, status); + return status; + } ++EXPORT_SYMBOL_GPL(__gpiod_export); ++ ++int gpiod_export(struct gpio_desc *desc, bool direction_may_change) ++{ ++ return __gpiod_export(desc, direction_may_change, NULL); ++} + EXPORT_SYMBOL_GPL(gpiod_export); + + static int match_export(struct device *dev, const void *desc) +--- a/include/asm-generic/gpio.h ++++ b/include/asm-generic/gpio.h +@@ -127,6 +127,12 @@ static inline int gpio_export(unsigned g + return gpiod_export(gpio_to_desc(gpio), direction_may_change); + } + ++int __gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name); ++static inline int gpio_export_with_name(unsigned gpio, bool direction_may_change, const char *name) ++{ ++ return __gpiod_export(gpio_to_desc(gpio), direction_may_change, name); ++} ++ + static inline int gpio_export_link(struct device *dev, const char *name, + unsigned gpio) + { +--- a/include/linux/gpio/consumer.h ++++ b/include/linux/gpio/consumer.h +@@ -668,6 +668,7 @@ static inline void devm_acpi_dev_remove_ + + #if IS_ENABLED(CONFIG_GPIOLIB) && IS_ENABLED(CONFIG_GPIO_SYSFS) + ++int _gpiod_export(struct gpio_desc *desc, bool direction_may_change, const char *name); + int gpiod_export(struct gpio_desc *desc, bool direction_may_change); + int gpiod_export_link(struct device *dev, const char *name, + struct gpio_desc *desc); +@@ -675,6 +676,13 @@ void gpiod_unexport(struct gpio_desc *de + + #else /* CONFIG_GPIOLIB && CONFIG_GPIO_SYSFS */ + ++static inline int _gpiod_export(struct gpio_desc *desc, ++ bool direction_may_change, ++ const char *name) ++{ ++ return -ENOSYS; ++} ++ + static inline int gpiod_export(struct gpio_desc *desc, + bool direction_may_change) + { diff --git a/root/target/linux/ipq40xx/patches-5.4/719-meiglink_slm750_support.patch b/root/target/linux/ipq40xx/patches-5.4/719-meiglink_slm750_support.patch new file mode 100644 index 00000000..9fa02a68 --- /dev/null +++ b/root/target/linux/ipq40xx/patches-5.4/719-meiglink_slm750_support.patch @@ -0,0 +1,35 @@ +Index: linux-5.4.137/drivers/usb/serial/option.c +=================================================================== +--- linux-5.4.137.orig/drivers/usb/serial/option.c ++++ linux-5.4.137/drivers/usb/serial/option.c +@@ -241,6 +241,8 @@ static void option_instat_callback(struc + #define UBLOX_PRODUCT_R6XX 0x90fa + /* These Yuga products use Qualcomm's vendor ID */ + #define YUGA_PRODUCT_CLM920_NC5 0x9625 ++/* These Meiglink products use Qualcomm's vendor ID */ ++#define MEIGLINK_PRODUCT_SLM750 0xf601 + + #define QUECTEL_VENDOR_ID 0x2c7c + /* These Quectel products use Quectel's vendor ID */ +@@ -1102,6 +1104,9 @@ static const struct usb_device_id option + /* u-blox products using Qualcomm vendor ID */ + { USB_DEVICE(QUALCOMM_VENDOR_ID, UBLOX_PRODUCT_R410M), + .driver_info = RSVD(1) | RSVD(3) }, ++ /* Meiglink products using Qualcomm vendor ID */ ++ // Works OK in case of some issues check macros that are used by Quectel Products ++ { USB_DEVICE(QUALCOMM_VENDOR_ID, MEIGLINK_PRODUCT_SLM750)}, + { USB_DEVICE(QUALCOMM_VENDOR_ID, UBLOX_PRODUCT_R6XX), + .driver_info = RSVD(3) }, + /* Quectel products using Quectel vendor ID */ +Index: linux-5.4.137/drivers/net/usb/qmi_wwan.c +=================================================================== +--- linux-5.4.137.orig/drivers/net/usb/qmi_wwan.c ++++ linux-5.4.137/drivers/net/usb/qmi_wwan.c +@@ -1171,6 +1171,7 @@ static const struct usb_device_id produc + {QMI_FIXED_INTF(0x05c6, 0x9079, 6)}, + {QMI_FIXED_INTF(0x05c6, 0x9079, 7)}, + {QMI_FIXED_INTF(0x05c6, 0x9079, 8)}, ++ {QMI_MATCH_FF_FF_FF(0x05c6, 0xf601)}, /* Meiglink SLM750 (in case of issues check if DTR flag setting is enough) */ + {QMI_FIXED_INTF(0x05c6, 0x9080, 5)}, + {QMI_FIXED_INTF(0x05c6, 0x9080, 6)}, + {QMI_FIXED_INTF(0x05c6, 0x9080, 7)},