From patchwork Mon Jun 6 00:44:06 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vincent Pelletier X-Patchwork-Id: 630629 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3rNGDG515Tz9t43 for ; Mon, 6 Jun 2016 10:44:14 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=XLR77lNn; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752030AbcFFAoL (ORCPT ); Sun, 5 Jun 2016 20:44:11 -0400 Received: from mail-pa0-f66.google.com ([209.85.220.66]:32794 "EHLO mail-pa0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751141AbcFFAoK (ORCPT ); Sun, 5 Jun 2016 20:44:10 -0400 Received: by mail-pa0-f66.google.com with SMTP id di3so10504093pab.0 for ; Sun, 05 Jun 2016 17:44:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:from:to:subject:message-id:mime-version; bh=5XpOm9FeeCZgsV9TU+E7fRi0GUDz1GuO5t/mm7TN7VY=; b=XLR77lNnYcrTDKJ/QcBeHGnkRGTMZTj76/DsAptO4GADaoEMBYIrDTU0Zs2WuOVqiY 7sAzC7WuIe5egUUuXADehsReC3+sQgqlm+0FXUbhUr/hCSfqCYzpfvlTqHdsy1Asilc/ nnc2GddEgvV1nRbnBrco74KxXHxUJEhVBon6Xg7VdG369FY93TuDLyf27ccMlT8QXYGH c82DAUo0rQNAGD0t7BQ8+WwtztQXE+m9LsAqSAfNpVjcPoSoqGKRDQTOy8BmH1P7b9RV HU4OTPZi/DOo7zZG+YZmMCD+pzhdoMNd9MsqKDDp3Bq+fRZ2VMlUk/khC5MugC4R6YSR qezQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:date:from:to:subject:message-id:mime-version; bh=5XpOm9FeeCZgsV9TU+E7fRi0GUDz1GuO5t/mm7TN7VY=; b=BZiJAhWZaYWNQk+S4A4sJyZGjpzkyFwvbNxx8AH9t9rzWpX5Rj99QUhgcam0eE5Ryg w9fzYjNBzPFqAF2wmcYCnVAB13X9wy0xL4PnIK7UcNxJGe5RHAEtzy1bWhN5CDW5irsY km3QLb1m7g7XZIOHqQM541As6c3QbKaLbIykFV+C5YJMZqVVOQ+lwiUgSk1f9HPgfBFE MYoY7FxuDKth0On6SCM78FfxJkq3iLXZ7yE32BfzPgwJSUcu8qq0IxBt72O7z24SURmV FrzLRIIQ1Oqf7NLkYxvojDIUPfYSojfZb7HWv2MQjxOLUyhwz0gxB09OhwmGxWLKetve h8Mg== X-Gm-Message-State: ALyK8tJXI2Mw/Et2D+aR5S/RKsrPsNj8MX3DeqjZKQNhqwjlwOczRV5mll6Gb85qXyiXVQ== X-Received: by 10.66.191.100 with SMTP id gx4mr21609767pac.128.1465173849248; Sun, 05 Jun 2016 17:44:09 -0700 (PDT) Received: from localhost (p11140-ipngn5801hodogaya.kanagawa.ocn.ne.jp. [222.148.106.140]) by smtp.gmail.com with ESMTPSA id w190sm22740920pfd.58.2016.06.05.17.44.08 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 05 Jun 2016 17:44:08 -0700 (PDT) Received: from localhost (localhost [127.0.0.1]) by localhost (Postfix) with ESMTPSA id 2DC76900808 for ; Mon, 6 Jun 2016 00:44:06 +0000 (GMT) Date: Mon, 6 Jun 2016 00:44:06 +0000 From: Vincent Pelletier To: linux-gpio@vger.kernel.org Subject: [RFC] qnap-tsx51: add new driver for leds and button support on QNAP TS-x51 series Message-ID: <20160606004406.29f016de@gmail.com> X-Mailer: Claws Mail 3.13.2 (GTK+ 2.24.30; x86_64-pc-linux-gnu) MIME-Version: 1.0 Sender: linux-gpio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-gpio@vger.kernel.org Hello, (please keep me CC'ed in replies, I'm not getting a majordomo subscription confirmation mail) I own a QNAP TS-651 NAS enclosure (the 6-drives variant of the TS-x51 product family). It is a regular x86-64, and it can work with vanilla kernel & generic distro as a replacement to vendor firmware. ACPI tables do not declare GPIOs used to interface with the enclosure: - two buttons for input - one red led per disk slot (for failure events) - USB activity led - two-colours status led (for off/green/orange/red result) I wrote the following platform driver, that I would like to contribute to the kernel. Could someone please review below patch ? It is my first attempt at writing a module from scratch, so watch out for naive mistakes. I see drivers using GPIOs should use descriptors instead of gpio number. I fail to see how I should convert this driver to use descriptors. Or at least, I like a lot that this module has extremely little actual code, as I would expect from something which essentially does the same work as ACPI tables. Is it also achievable with descriptors ? About disk leds, there exist 2, 4, 6 and 8-drives versions of this enclosure. I do not know how to detect which one the module is being loaded on, so I declare all 8 leds, and userland should drive leds which match detected drives. For completeness, I attached udev configuration file (to have device symlinks correctly mapping SCSI devices to slots - 6 drives version) and "mdadm --monitor --program"-compatible led control shell script (which depends on udev disk symlinks and led names being consistent). Regards, Vincent Pelletier From 8c59f4f1c4f0c69b9168979fdf130b301b1be20b Mon Sep 17 00:00:00 2001 Message-Id: <8c59f4f1c4f0c69b9168979fdf130b301b1be20b.1465170970.git.plr.vincent@gmail.com> From: Vincent Pelletier Date: Mon, 17 Aug 2015 18:50:13 +0200 Subject: qnap-tsx51: add new driver for leds and button support on QNAP TS-x51 series This adds QNAP TS-x51 driver. It exposes led and buttons present on this NAS enclosure to userland for convenient access. Ideally, all this driver does should be declared by ACPI, but even SuperIO GPIO pins are not. Also, ideally this driver should check DMI strings, but OEM did not initialise any. Signed-off-by: Vincent Pelletier --- drivers/platform/x86/Kconfig | 9 ++ drivers/platform/x86/Makefile | 1 + drivers/platform/x86/qnap-tsx51.c | 168 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 178 insertions(+) create mode 100644 drivers/platform/x86/qnap-tsx51.c diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index ed2004b..4da05bc 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -1001,4 +1001,13 @@ config INTEL_TELEMETRY used to get various SoC events and parameters directly via debugfs files. Various tools may use this interface for SoC state monitoring. + +config QNAP_TSX51 + tristate "QNAP TS-x51 NAS" + select LEDS_GPIO + select KEYBOARD_GPIO_POLLED + select GPIO_F7188X + ---help--- + This driver provides support for QNAP TS-x51 NAS enclosure + leds (drive error, status, usb) and buttons. endif # X86_PLATFORM_DEVICES diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index 448443c..e03c507 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile @@ -69,3 +69,4 @@ obj-$(CONFIG_INTEL_PUNIT_IPC) += intel_punit_ipc.o obj-$(CONFIG_INTEL_TELEMETRY) += intel_telemetry_core.o \ intel_telemetry_pltdrv.o \ intel_telemetry_debugfs.o +obj-$(CONFIG_QNAP_TSX51) += qnap-tsx51.o diff --git a/drivers/platform/x86/qnap-tsx51.c b/drivers/platform/x86/qnap-tsx51.c new file mode 100644 index 0000000..c6304b9 --- /dev/null +++ b/drivers/platform/x86/qnap-tsx51.c @@ -0,0 +1,168 @@ +/* + * Support for LEDs and buttons available on the QNAP TS-x51 NAS. + * + * Copyright (C) 2015 Vincent Pelletier + */ + +#include +#include +#include +#include +#include + +static void qnap_tsx51_device_pdev_release(struct device *dev); + +static struct gpio_led qnap_tsx51_led[] = { + { + .name = "qnap_tsx51:green:status", + .gpio = 62, + .active_low = 1, + .default_state = LEDS_GPIO_DEFSTATE_ON, + }, + { + .name = "qnap_tsx51:red:status", + .gpio = 63, + .active_low = 1, + }, + { + .name = "qnap_tsx51:blue:usb", + .default_trigger = "usb-host", + .gpio = 17, + .active_low = 1, + }, + { + .name = "hdd1:red:sata", + .gpio = 70, + .active_low = 1, + }, + { + .name = "hdd2:red:sata", + .gpio = 71, + .active_low = 1, + }, + { + .name = "hdd3:red:sata", + .gpio = 72, + .active_low = 1, + }, + { + .name = "hdd4:red:sata", + .gpio = 73, + .active_low = 1, + }, + { + .name = "hdd5:red:sata", + .gpio = 74, + .active_low = 1, + }, + { + .name = "hdd6:red:sata", + .gpio = 75, + .active_low = 1, + }, + { + .name = "hdd7:red:sata", + .gpio = 76, + .active_low = 1, + }, + { + .name = "hdd8:red:sata", + .gpio = 77, + .active_low = 1, + }, +}; + +static struct gpio_led_platform_data qnap_tsx51_led_data = { + .num_leds = ARRAY_SIZE(qnap_tsx51_led), + .leds = qnap_tsx51_led, +}; + +static struct platform_device qnap_tsx51_leds_dev = { + .name = "leds-gpio", + .id = -1, + .dev = { + .release = qnap_tsx51_device_pdev_release, + .platform_data = &qnap_tsx51_led_data, + }, +}; + +static struct gpio_keys_button qnap_tsx51_gpio_buttons[] = { + { + .code = KEY_COPY, + .gpio = 12, + .active_low = 1, + .desc = "Copy button", + .type = EV_KEY, + .wakeup = 0, + .debounce_interval = 100, + .can_disable = 0, + }, + { + .code = KEY_RESTART, + .gpio = 61, + .active_low = 1, + .desc = "Reset button", + .type = EV_KEY, + .wakeup = 0, + .debounce_interval = 100, + .can_disable = 0, + }, +}; + +static struct gpio_keys_platform_data qnap_tsx51_buttons_data = { + .buttons = qnap_tsx51_gpio_buttons, + .nbuttons = ARRAY_SIZE(qnap_tsx51_gpio_buttons), + .poll_interval = 20, +}; + +static struct platform_device qnap_tsx51_buttons_dev = { + .name = "gpio-keys-polled", + .id = -1, + .dev = { + .release = qnap_tsx51_device_pdev_release, + .platform_data = &qnap_tsx51_buttons_data, + }, +}; + +static struct platform_device *qnap_tsx51_devs[] = { + &qnap_tsx51_buttons_dev, + &qnap_tsx51_leds_dev, +}; + +static void qnap_tsx51_device_pdev_release(struct device *dev) +{ +/* + * Needed to silence this message: + * Device 'xxx' does not have a release() function, it is broken and must be + * fixed. + */ +} + +static int __init qnap_tsx51_init(void) +{ + int ret; + + ret = request_module("gpio_f7188x"); + if (ret) + return ret; + + return platform_add_devices( + qnap_tsx51_devs, + ARRAY_SIZE(qnap_tsx51_devs) + ); + +} + +static void __exit qnap_tsx51_exit(void) +{ + int i; + for (i = 0; i < ARRAY_SIZE(qnap_tsx51_devs); i++) + platform_device_unregister(qnap_tsx51_devs[i]); +} + +module_init(qnap_tsx51_init); +module_exit(qnap_tsx51_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("QNAP TS-x51 NAS"); +MODULE_AUTHOR("Vincent Pelletier ");