linux-mips.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/1] KB3310B MFD Driver for Lemote Yeeloong laptops.
@ 2019-03-30  8:18 Tom Li
  2019-03-30  8:18 ` [PATCH 1/1] mfd: yeeloong_kb3310b: support KB3310B EC " Tom Li
  0 siblings, 1 reply; 4+ messages in thread
From: Tom Li @ 2019-03-30  8:18 UTC (permalink / raw)
  To: Lee Jones; +Cc: linux-mips, Paul Burton, linux-kernel, Tom Li

This is a resend of the first patch ("[PATCH v3 1/7]") in the patchset
"[PATCH v3 0/7] Preliminary Platform Driver Support for Lemote Yeeloong
Laptops" [0], which introduced a new MFD driver.

The original patchset never arrived to Lee's inbox. so I resend the
patch to facilitate review.

It features the following...

* Create a MFD driver for KB3310B controller, and move the original
KB3310B controller code from mips/loongson64 to our new MFD driver.
This needs to be reviewed by the MFD subsystem maintainer before the
following can proceed.

* Subdrivers - hwmon, battery, backlight, lcd and hotkey are registered
as MFD cells in the MFD driver. It means onlf the MFD driver is resposible
to register the upcoming subdrivers, the core board files mips/loongson64/
will not contain unrelated code.

[0] https://lore.kernel.org/linux-mips/20190306120113.648-1-tomli@tomli.me/T/#m2a6e18afbb62ceb535a859181d8485916b30a63f

Thanks,

Yifeng Li (1):
  mfd: yeeloong_kb3310b: support KB3310B EC for Lemote Yeeloong laptops.

 MAINTAINERS                          |   7 +
 drivers/mfd/Kconfig                  |  10 ++
 drivers/mfd/Makefile                 |   1 +
 drivers/mfd/yeeloong_kb3310b.c       | 200 +++++++++++++++++++++++++
 include/linux/mfd/yeeloong_kb3310b.h | 211 +++++++++++++++++++++++++++
 5 files changed, 429 insertions(+)
 create mode 100644 drivers/mfd/yeeloong_kb3310b.c
 create mode 100644 include/linux/mfd/yeeloong_kb3310b.h

-- 
2.20.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/1] mfd: yeeloong_kb3310b: support KB3310B EC for Lemote Yeeloong laptops.
  2019-03-30  8:18 [PATCH 0/1] KB3310B MFD Driver for Lemote Yeeloong laptops Tom Li
@ 2019-03-30  8:18 ` Tom Li
  2019-04-03  8:36   ` Lee Jones
  2020-01-23  0:22   ` Matt Turner
  0 siblings, 2 replies; 4+ messages in thread
From: Tom Li @ 2019-03-30  8:18 UTC (permalink / raw)
  To: Lee Jones; +Cc: linux-mips, Paul Burton, linux-kernel, Tom Li, Yifeng Li

From: Yifeng Li <tomli@tomli.me>

Lemote Yeeloong is a laptop powered by Loongson 2F MIPS processor,
primarily a demo platform for hobbyists and developers. It uses an
ENE KB3310B Embedded Controller with customized firmware to implement
hardware and power management.

A monolithic platform driver code for those functionality has existed
out-of-tree for many years. This commit creates a MFD driver for the EC
chip on Yeeloong laptop to isolate EC-related code from core MIPS code,
and serves as the foundation of various subdrivers.

NOTE: A regmap could be the reasonable abstraction for I/O, but (1)
it requires some additional refactoring to convert the shutdown/wakeup
routines in board files to subdrivers, and (2) we're only using simple
reads/writes, repmap only adds boilerplates to the existing files without
additional benefits. We simply export the EC-related functions for now,
until we come back to refactor the board files.

Signed-off-by: Yifeng Li <tomli@tomli.me>
---
 MAINTAINERS                          |   7 +
 drivers/mfd/Kconfig                  |  10 ++
 drivers/mfd/Makefile                 |   1 +
 drivers/mfd/yeeloong_kb3310b.c       | 200 +++++++++++++++++++++++++
 include/linux/mfd/yeeloong_kb3310b.h | 211 +++++++++++++++++++++++++++
 5 files changed, 429 insertions(+)
 create mode 100644 drivers/mfd/yeeloong_kb3310b.c
 create mode 100644 include/linux/mfd/yeeloong_kb3310b.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 51029a425dbe..208f19801a23 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -16839,6 +16839,13 @@ S:	Maintained
 F:	Documentation/input/devices/yealink.rst
 F:	drivers/input/misc/yealink.*
 
+YEELOONG ENE KB3310B MFD DRIVER
+M:	Tom Li <tomli@tomli.me>
+L:	linux-mips@vger.kernel.org
+S:	Maintained
+F:	drivers/mfd/yeeloong_kb3310b.c
+F:	include/linux/mfd/yeeloong_kb3310b.h
+
 Z8530 DRIVER FOR AX.25
 M:	Joerg Reuter <jreuter@yaina.de>
 W:	http://yaina.de/jreuter/
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index f461460a2aeb..a6da8cce72fc 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1872,6 +1872,16 @@ config MFD_STM32_TIMERS
 	  for PWM and IIO Timer. This driver allow to share the
 	  registers between the others drivers.
 
+config MFD_YEELOONG_KB3310B
+	bool "ENE KB3310B Embedded Controller on Lemote Yeeloong laptops"
+	depends on (MIPS && LEMOTE_MACH2F) || COMPILE_TEST
+	select MFD_CORE
+	help
+          Select this option to enable ENE KB3310B Embedded Controller
+          driver used on Lemote Yeeloong laptops, providing power, battery
+          and backlight services. This is a mandatory dependency for
+          Lemote 2F systems.
+
 menu "Multimedia Capabilities Port drivers"
 	depends on ARCH_SA1100
 
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 12980a4ad460..a3446ce7c384 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -224,6 +224,7 @@ obj-$(CONFIG_MFD_HI655X_PMIC)   += hi655x-pmic.o
 obj-$(CONFIG_MFD_DLN2)		+= dln2.o
 obj-$(CONFIG_MFD_RT5033)	+= rt5033.o
 obj-$(CONFIG_MFD_SKY81452)	+= sky81452.o
+obj-$(CONFIG_MFD_YEELOONG_KB3310B) += yeeloong_kb3310b.o
 
 intel-soc-pmic-objs		:= intel_soc_pmic_core.o intel_soc_pmic_crc.o
 obj-$(CONFIG_INTEL_SOC_PMIC)	+= intel-soc-pmic.o
diff --git a/drivers/mfd/yeeloong_kb3310b.c b/drivers/mfd/yeeloong_kb3310b.c
new file mode 100644
index 000000000000..423d5ced2f65
--- /dev/null
+++ b/drivers/mfd/yeeloong_kb3310b.c
@@ -0,0 +1,200 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/*
+ * MFD driver for ENE KB3310B embedded controller on Lemote Yeeloong laptops
+ *
+ * Copyright (C) 2008 Lemote Inc.
+ * Author: liujl <liujl@lemote.com>, 2008-04-20
+ *
+ * Copyright (C) 2019 Yifeng Li
+ * Author: Yifeng Li <tomli@tomli.me>
+ *
+ * This is a MFD driver for the ENE KB3310B Embedded Controller for Lemote
+ * Yeeloong laptops to provide utility functions to access the chip from
+ * subdrivers, and handle events and interrupts in board files. This is a
+ * special-purpose driver, and it's only used on Lemote Yeeloong laptops,
+ * and is a mandatory dependency.
+ *
+ * NOTE: A regmap could be the reasonable abstraction for I/O, but (1)
+ * it requires some additional refactoring to convert the shutdown/wakeup
+ * routines in board files to subdrivers, and (2) we're only using simple
+ * reads/writes, repmap only adds boilerplates to the existing files without
+ * additional benefits. We simply export the EC-related functions for now,
+ * until we come back to refactor the board files.
+ */
+
+#include <linux/export.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/core.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+
+#include <linux/mfd/yeeloong_kb3310b.h>
+
+#ifdef pr_fmt
+#undef pr_fmt
+#endif
+
+#define DRV_NAME "yeeloong_kb3310b"
+#define pr_fmt(fmt) DRV_NAME ": " fmt
+
+/*
+ * Most drivers, such as battery or backlight drivers, uses the I/O ports to
+ * access the Index Registers to obtain hardware status and information from
+ * EC chip.
+ */
+static struct kb3310b_chip *kb3310b_fwinfo;
+
+static const struct mfd_cell kb3310b_cells[] = {
+	{ .name = "yeeloong_sci" },
+	{ .name = "yeeloong_hwmon" },
+	{ .name = "yeeloong_battery" },
+	{ .name = "yeeloong_backlight" },
+	{ .name = "yeeloong_lcd" },
+	{ .name = "yeeloong_hotkey" },
+};
+
+static DEFINE_SPINLOCK(kb3310b_index_lock);
+
+u8 kb3310b_read(u16 reg)
+{
+	unsigned long flags;
+	u8 val;
+
+	spin_lock_irqsave(&kb3310b_index_lock, flags);
+
+	outb((reg & 0xff00) >> 8, KB3310B_IO_PORT_HIGH);
+	outb((reg & 0x00ff), KB3310B_IO_PORT_LOW);
+	val = inb(KB3310B_IO_PORT_DATA);
+
+	spin_unlock_irqrestore(&kb3310b_index_lock, flags);
+
+	return val;
+}
+EXPORT_SYMBOL_GPL(kb3310b_read);
+
+void kb3310b_write(u16 reg, u8 val)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&kb3310b_index_lock, flags);
+
+	outb((reg & 0xff00) >> 8, KB3310B_IO_PORT_HIGH);
+	outb((reg & 0x00ff), KB3310B_IO_PORT_LOW);
+	outb(val, KB3310B_IO_PORT_DATA);
+	inb(KB3310B_IO_PORT_DATA);  /* flush pending writes */
+
+	spin_unlock_irqrestore(&kb3310b_index_lock, flags);
+}
+EXPORT_SYMBOL_GPL(kb3310b_write);
+
+bool kb3310b_fw_earlier(char *version)
+{
+	return (strncasecmp(kb3310b_fwinfo->version,
+				version, KB3310B_VERSION_LEN) < 0);
+}
+EXPORT_SYMBOL_GPL(kb3310b_fw_earlier);
+
+static int kb3310b_probe(struct platform_device *pdev)
+{
+	kb3310b_fwinfo = dev_get_platdata(&pdev->dev);
+	pr_info("firmware version %s", kb3310b_fwinfo->version);
+
+	return devm_mfd_add_devices(&pdev->dev, -1, kb3310b_cells,
+				    ARRAY_SIZE(kb3310b_cells), NULL, 0, NULL);
+}
+
+static struct platform_driver kb3310b_driver = {
+	.driver = {
+		   .name = "yeeloong_kb3310b",
+	},
+	.probe = kb3310b_probe,
+};
+builtin_platform_driver(kb3310b_driver);
+
+/*
+ * For interrupt handling and power management, the EC chip is also needed to
+ * be queried from the board file at arch/mips/loongson64, through a separate
+ * command port.
+ */
+
+/*
+ * This function is used for EC command writes and corresponding status queries.
+ */
+int kb3310b_query_seq(unsigned char cmd)
+{
+	int timeout;
+	unsigned char status;
+
+	static DEFINE_SPINLOCK(kb3310b_command_lock);
+	unsigned long flags;
+
+	spin_lock_irqsave(&kb3310b_command_lock, flags);
+
+	/* make chip goto reset mode */
+	udelay(KB3310B_REG_UDELAY);
+	outb(cmd, KB3310B_CMD_PORT);
+	udelay(KB3310B_REG_UDELAY);
+
+	/* check if the command is received by EC */
+	timeout = KB3310B_CMD_TIMEOUT;
+	status = inb(KB3310B_STS_PORT);
+	while (timeout-- && (status & (1 << 1))) {
+		status = inb(KB3310B_STS_PORT);
+		udelay(KB3310B_REG_UDELAY);
+	}
+
+	spin_unlock_irqrestore(&kb3310b_command_lock, flags);
+
+	if (timeout <= 0) {
+		pr_err("(%x/NA) failed to issue command %d, no response!\n",
+			timeout, cmd);
+		return -EINVAL;
+	}
+
+	pr_info("(%x/%x) issued command %d, status: 0x%x\n",
+		 timeout, KB3310B_CMD_TIMEOUT - timeout,
+		 cmd, status);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(kb3310b_query_seq);
+
+/*
+ * Send query command to EC to get the proper event number.
+ */
+int kb3310b_query_event_num(void)
+{
+	return kb3310b_query_seq(KB3310B_CMD_GET_EVENT_NUM);
+}
+EXPORT_SYMBOL_GPL(kb3310b_query_event_num);
+
+/*
+ * Get event number from EC.
+ *
+ * NOTE: This routine must follow the query_event_num function in the
+ * interrupt.
+ */
+int kb3310b_get_event_num(void)
+{
+	int timeout = 100;
+	unsigned char value;
+	unsigned char status;
+
+	udelay(KB3310B_REG_UDELAY);
+	status = inb(KB3310B_STS_PORT);
+	udelay(KB3310B_REG_UDELAY);
+	while (timeout-- && !(status & (1 << 0))) {
+		status = inb(KB3310B_STS_PORT);
+		udelay(KB3310B_REG_UDELAY);
+	}
+	if (timeout <= 0) {
+		pr_info("%s: get event number timeout.\n", __func__);
+		return -EINVAL;
+	}
+	value = inb(KB3310B_DAT_PORT);
+	udelay(KB3310B_REG_UDELAY);
+
+	return value;
+}
+EXPORT_SYMBOL_GPL(kb3310b_get_event_num);
diff --git a/include/linux/mfd/yeeloong_kb3310b.h b/include/linux/mfd/yeeloong_kb3310b.h
new file mode 100644
index 000000000000..ba8b82153bcd
--- /dev/null
+++ b/include/linux/mfd/yeeloong_kb3310b.h
@@ -0,0 +1,211 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/*
+ * MFD driver for ENE KB3310B embedded controller on Lemote Yeeloong laptops
+ *
+ * Copyright (C) 2008 Lemote Inc.
+ * Author: liujl <liujl@lemote.com>, 2008-04-20
+ *
+ * Copyright (C) 2019 Yifeng Li
+ * Author: Yifeng Li <tomli@tomli.me>
+ */
+
+#ifndef __LINUX_MFD_YEELOONG_KB3310B_H
+#define __LINUX_MFD_YEELOONG_KB3310B_H
+
+extern u8 kb3310b_read(u16 reg);
+extern void kb3310b_write(u16 reg, u8 val);
+extern bool kb3310b_fw_earlier(char *version);
+extern int kb3310b_query_seq(unsigned char cmd);
+extern int kb3310b_query_event_num(void);
+extern int kb3310b_get_event_num(void);
+
+typedef int (*sci_handler) (int status);
+
+extern int yeeloong_sci_register_notify(struct notifier_block *nb);
+extern int yeeloong_sci_unregister_notify(struct notifier_block *nb);
+
+#define KB3310B_VERSION_LEN 8
+
+struct kb3310b_chip {
+	char version[KB3310B_VERSION_LEN];
+};
+
+#define KB3310B_SCI_IRQ_NUM	0x0A
+
+/*
+ * The following registers are determined by the EC index configuration.
+ * 1, fill the PORT_HIGH as EC register high part.
+ * 2, fill the PORT_LOW as EC register low part.
+ * 3, fill the PORT_DATA as EC register write data or get the data from it.
+ */
+#define KB3310B_IO_PORT_HIGH	0x0381
+#define KB3310B_IO_PORT_LOW	0x0382
+#define KB3310B_IO_PORT_DATA	0x0383
+
+/*
+ * EC delay time is 500us for register and status access
+ */
+#define KB3310B_REG_UDELAY	500
+#define KB3310B_CMD_TIMEOUT	0x1000
+
+/*
+ * EC access port for SCI communication
+ */
+#define KB3310B_CMD_PORT		0x66
+#define KB3310B_STS_PORT		0x66
+#define KB3310B_DAT_PORT		0x62
+#define KB3310B_CMD_INIT_IDLE_MODE	0xdd
+#define KB3310B_CMD_EXIT_IDLE_MODE	0xdf
+#define KB3310B_CMD_INIT_RESET_MODE	0xd8
+#define KB3310B_CMD_REBOOT_SYSTEM	0x8c
+#define KB3310B_CMD_GET_EVENT_NUM	0x84
+#define KB3310B_CMD_PROGRAM_PIECE	0xda
+
+/* temperature & fan registers */
+#define KB3310B_REG_TEMPERATURE_VALUE	0xF458
+#define KB3310B_REG_FAN_AUTO_MAN_SWITCH 0xF459
+#define KB3310B_BIT_FAN_AUTO		0
+#define KB3310B_BIT_FAN_MANUAL		1
+#define KB3310B_REG_FAN_CONTROL		0xF4D2
+#define KB3310B_BIT_FAN_CONTROL_ON	(1 << 0)
+#define KB3310B_BIT_FAN_CONTROL_OFF	(0 << 0)
+#define KB3310B_REG_FAN_STATUS		0xF4DA
+#define KB3310B_BIT_FAN_STATUS_ON	(1 << 0)
+#define KB3310B_BIT_FAN_STATUS_OFF	(0 << 0)
+#define KB3310B_REG_FAN_SPEED_HIGH	0xFE22
+#define KB3310B_REG_FAN_SPEED_LOW	0xFE23
+#define KB3310B_REG_FAN_SPEED_LEVEL	0xF4CC
+
+/* fan speed divider */
+#define KB3310B_FAN_SPEED_DIVIDER	480000	/* (60*1000*1000/62.5/2)*/
+
+/* battery registers */
+#define KB3310B_REG_BAT_DESIGN_CAP_HIGH		0xF77D
+#define KB3310B_REG_BAT_DESIGN_CAP_LOW		0xF77E
+#define KB3310B_REG_BAT_FULLCHG_CAP_HIGH	0xF780
+#define KB3310B_REG_BAT_FULLCHG_CAP_LOW		0xF781
+#define KB3310B_REG_BAT_DESIGN_VOL_HIGH		0xF782
+#define KB3310B_REG_BAT_DESIGN_VOL_LOW		0xF783
+#define KB3310B_REG_BAT_CURRENT_HIGH		0xF784
+#define KB3310B_REG_BAT_CURRENT_LOW		0xF785
+#define KB3310B_REG_BAT_VOLTAGE_HIGH		0xF786
+#define KB3310B_REG_BAT_VOLTAGE_LOW		0xF787
+#define KB3310B_REG_BAT_TEMPERATURE_HIGH	0xF788
+#define KB3310B_REG_BAT_TEMPERATURE_LOW		0xF789
+#define KB3310B_REG_BAT_RELATIVE_CAP_HIGH	0xF492
+#define KB3310B_REG_BAT_RELATIVE_CAP_LOW	0xF493
+#define KB3310B_REG_BAT_VENDOR			0xF4C4
+#define KB3310B_FLAG_BAT_VENDOR_SANYO		0x01
+#define KB3310B_FLAG_BAT_VENDOR_SIMPLO		0x02
+#define KB3310B_REG_BAT_CELL_COUNT		0xF4C6
+#define KB3310B_FLAG_BAT_CELL_3S1P		0x03
+#define KB3310B_FLAG_BAT_CELL_3S2P		0x06
+#define KB3310B_REG_BAT_CHARGE			0xF4A2
+#define KB3310B_FLAG_BAT_CHARGE_DISCHARGE	0x01
+#define KB3310B_FLAG_BAT_CHARGE_CHARGE		0x02
+#define KB3310B_FLAG_BAT_CHARGE_ACPOWER		0x00
+#define KB3310B_REG_BAT_STATUS			0xF4B0
+#define KB3310B_BIT_BAT_STATUS_LOW		(1 << 5)
+#define KB3310B_BIT_BAT_STATUS_DESTROY		(1 << 2)
+#define KB3310B_BIT_BAT_STATUS_FULL		(1 << 1)
+#define KB3310B_BIT_BAT_STATUS_IN		(1 << 0)
+#define KB3310B_REG_BAT_CHARGE_STATUS		0xF4B1
+#define KB3310B_BIT_BAT_CHARGE_STATUS_OVERTEMP	(1 << 2)
+#define KB3310B_BIT_BAT_CHARGE_STATUS_PRECHG	(1 << 1)
+#define KB3310B_REG_BAT_STATE			0xF482
+#define KB3310B_BIT_BAT_STATE_CHARGING		(1 << 1)
+#define KB3310B_BIT_BAT_STATE_DISCHARGING	(1 << 0)
+#define KB3310B_REG_BAT_POWER			0xF440
+#define KB3310B_BIT_BAT_POWER_S3		(1 << 2)
+#define KB3310B_BIT_BAT_POWER_ON		(1 << 1)
+#define KB3310B_BIT_BAT_POWER_ACIN		(1 << 0)
+
+/* other registers */
+
+/* Audio: rd/wr */
+#define KB3310B_REG_AUDIO_VOLUME	0xF46C
+#define KB3310B_REG_AUDIO_MUTE		0xF4E7
+#define KB3310B_REG_AUDIO_BEEP		0xF4D0
+
+/* USB port power or not: rd/wr */
+#define KB3310B_REG_USB0_FLAG		0xF461
+#define KB3310B_REG_USB1_FLAG		0xF462
+#define KB3310B_REG_USB2_FLAG		0xF463
+#define KB3310B_BIT_USB_FLAG_ON		1
+#define KB3310B_BIT_USB_FLAG_OFF	0
+
+/* LID */
+#define KB3310B_REG_LID_DETECT		0xF4BD
+#define KB3310B_BIT_LID_DETECT_ON	1
+#define KB3310B_BIT_LID_DETECT_OFF	0
+
+/* CRT */
+#define KB3310B_REG_CRT_DETECT		0xF4AD
+#define KB3310B_BIT_CRT_DETECT_PLUG	1
+#define KB3310B_BIT_CRT_DETECT_UNPLUG	0
+
+/* LCD backlight brightness adjust: 9 levels */
+#define KB3310B_REG_DISPLAY_BRIGHTNESS	0xF4F5
+
+/* Black screen status */
+#define KB3310B_REG_DISPLAY_LCD		0xF79F
+#define KB3310B_BIT_DISPLAY_LCD_ON	1
+#define KB3310B_BIT_DISPLAY_LCD_OFF	0
+
+/* LCD backlight control: off/restore */
+#define KB3310B_REG_BACKLIGHT_CTRL	0xF7BD
+#define KB3310B_BIT_BACKLIGHT_ON	1
+#define KB3310B_BIT_BACKLIGHT_OFF	0
+
+/* Reset the machine auto-clear: rd/wr */
+#define KB3310B_REG_RESET		0xF4EC
+#define KB3310B_BIT_RESET_ON		1
+
+/* Light the LED: rd/wr */
+#define KB3310B_REG_LED			0xF4C8
+#define KB3310B_BIT_LED_RED_POWER	(1 << 0)
+#define KB3310B_BIT_LED_ORANGE_POWER	(1 << 1)
+#define KB3310B_BIT_LED_GREEN_CHARGE	(1 << 2)
+#define KB3310B_BIT_LED_RED_CHARGE	(1 << 3)
+#define KB3310B_BIT_LED_NUMLOCK		(1 << 4)
+
+/* Test LED mode, all LED on/off */
+#define KB3310B_REG_LED_TEST		0xF4C2
+#define KB3310B_BIT_LED_TEST_IN		1
+#define KB3310B_BIT_LED_TEST_OUT	0
+
+/* Camera on/off */
+#define KB3310B_REG_CAMERA_STATUS	0xF46A
+#define KB3310B_BIT_CAMERA_STATUS_ON	1
+#define KB3310B_BIT_CAMERA_STATUS_OFF	0
+#define KB3310B_REG_CAMERA_CONTROL	0xF7B7
+#define KB3310B_BIT_CAMERA_CONTROL_OFF	0
+#define KB3310B_BIT_CAMERA_CONTROL_ON	1
+
+/* WLAN Status */
+#define KB3310B_REG_WLAN		0xF4FA
+#define KB3310B_BIT_WLAN_ON		1
+#define KB3310B_BIT_WLAN_OFF		0
+
+/* SCI Event Number from EC */
+enum {
+	KB3310B_EVENT_START = 0x22,
+	KB3310B_EVENT_LID = 0x23,	   /* LID open/close */
+	KB3310B_EVENT_DISPLAY_TOGGLE,	   /* Fn+F3 for display switch */
+	KB3310B_EVENT_SLEEP,		   /* Fn+F1 for entering sleep mode */
+	KB3310B_EVENT_OVERTEMP,		   /* Over-temperature occurred */
+	KB3310B_EVENT_CRT_DETECT,	   /* CRT is connected */
+	KB3310B_EVENT_CAMERA,		   /* Camera on/off */
+	KB3310B_EVENT_USB_OC2,		   /* USB2 Overcurrent occurred */
+	KB3310B_EVENT_USB_OC0,		   /* USB0 Overcurrent occurred */
+	KB3310B_EVENT_BLACK_SCREEN,	   /* Turn on/off backlight */
+	KB3310B_EVENT_AUDIO_MUTE,	   /* Mute on/off */
+	KB3310B_EVENT_DISPLAY_BRIGHTNESS,  /* LCD backlight brightness adjust */
+	KB3310B_EVENT_AC_BAT,		   /* AC & Battery relative issue */
+	KB3310B_EVENT_AUDIO_VOLUME,	   /* Volume adjust */
+	KB3310B_EVENT_WLAN,		   /* WLAN on/off */
+	KB3310B_EVENT_END
+};
+
+#endif /* !__LINUX_MFD_YEELOONG_KB3310B_H */
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/1] mfd: yeeloong_kb3310b: support KB3310B EC for Lemote Yeeloong laptops.
  2019-03-30  8:18 ` [PATCH 1/1] mfd: yeeloong_kb3310b: support KB3310B EC " Tom Li
@ 2019-04-03  8:36   ` Lee Jones
  2020-01-23  0:22   ` Matt Turner
  1 sibling, 0 replies; 4+ messages in thread
From: Lee Jones @ 2019-04-03  8:36 UTC (permalink / raw)
  To: Tom Li; +Cc: linux-mips, Paul Burton, linux-kernel, Yifeng Li

On Sat, 30 Mar 2019, Tom Li wrote:

> From: Yifeng Li <tomli@tomli.me>
> 
> Lemote Yeeloong is a laptop powered by Loongson 2F MIPS processor,
> primarily a demo platform for hobbyists and developers. It uses an
> ENE KB3310B Embedded Controller with customized firmware to implement
> hardware and power management.
> 
> A monolithic platform driver code for those functionality has existed
> out-of-tree for many years. This commit creates a MFD driver for the EC
> chip on Yeeloong laptop to isolate EC-related code from core MIPS code,
> and serves as the foundation of various subdrivers.
> 
> NOTE: A regmap could be the reasonable abstraction for I/O, but (1)
> it requires some additional refactoring to convert the shutdown/wakeup
> routines in board files to subdrivers, and (2) we're only using simple
> reads/writes, repmap only adds boilerplates to the existing files without
> additional benefits. We simply export the EC-related functions for now,
> until we come back to refactor the board files.
> 
> Signed-off-by: Yifeng Li <tomli@tomli.me>
> ---
>  MAINTAINERS                          |   7 +
>  drivers/mfd/Kconfig                  |  10 ++
>  drivers/mfd/Makefile                 |   1 +
>  drivers/mfd/yeeloong_kb3310b.c       | 200 +++++++++++++++++++++++++
>  include/linux/mfd/yeeloong_kb3310b.h | 211 +++++++++++++++++++++++++++
>  5 files changed, 429 insertions(+)
>  create mode 100644 drivers/mfd/yeeloong_kb3310b.c
>  create mode 100644 include/linux/mfd/yeeloong_kb3310b.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 51029a425dbe..208f19801a23 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -16839,6 +16839,13 @@ S:	Maintained
>  F:	Documentation/input/devices/yealink.rst
>  F:	drivers/input/misc/yealink.*
>  
> +YEELOONG ENE KB3310B MFD DRIVER

I assume you will want to keep an eye on more than just the parent
driver.  I would kill the "MFD DRIVER" bit and add additional files to
the file list as and when they are committed.

> +M:	Tom Li <tomli@tomli.me>
> +L:	linux-mips@vger.kernel.org
> +S:	Maintained
> +F:	drivers/mfd/yeeloong_kb3310b.c
> +F:	include/linux/mfd/yeeloong_kb3310b.h
> +
>  Z8530 DRIVER FOR AX.25
>  M:	Joerg Reuter <jreuter@yaina.de>
>  W:	http://yaina.de/jreuter/
> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
> index f461460a2aeb..a6da8cce72fc 100644
> --- a/drivers/mfd/Kconfig
> +++ b/drivers/mfd/Kconfig
> @@ -1872,6 +1872,16 @@ config MFD_STM32_TIMERS
>  	  for PWM and IIO Timer. This driver allow to share the
>  	  registers between the others drivers.
>  
> +config MFD_YEELOONG_KB3310B
> +	bool "ENE KB3310B Embedded Controller on Lemote Yeeloong laptops"
> +	depends on (MIPS && LEMOTE_MACH2F) || COMPILE_TEST

Doesn't LEMOTE_MACH2F already depend on MIPS?

> +	select MFD_CORE
> +	help
> +          Select this option to enable ENE KB3310B Embedded Controller
> +          driver used on Lemote Yeeloong laptops, providing power, battery
> +          and backlight services. This is a mandatory dependency for
> +          Lemote 2F systems.

There should only be 2 spaces '  ' indent here.

>  menu "Multimedia Capabilities Port drivers"
>  	depends on ARCH_SA1100
>  
> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
> index 12980a4ad460..a3446ce7c384 100644
> --- a/drivers/mfd/Makefile
> +++ b/drivers/mfd/Makefile
> @@ -224,6 +224,7 @@ obj-$(CONFIG_MFD_HI655X_PMIC)   += hi655x-pmic.o
>  obj-$(CONFIG_MFD_DLN2)		+= dln2.o
>  obj-$(CONFIG_MFD_RT5033)	+= rt5033.o
>  obj-$(CONFIG_MFD_SKY81452)	+= sky81452.o
> +obj-$(CONFIG_MFD_YEELOONG_KB3310B) += yeeloong_kb3310b.o
>  
>  intel-soc-pmic-objs		:= intel_soc_pmic_core.o intel_soc_pmic_crc.o
>  obj-$(CONFIG_INTEL_SOC_PMIC)	+= intel-soc-pmic.o
> diff --git a/drivers/mfd/yeeloong_kb3310b.c b/drivers/mfd/yeeloong_kb3310b.c
> new file mode 100644
> index 000000000000..423d5ced2f65
> --- /dev/null
> +++ b/drivers/mfd/yeeloong_kb3310b.c
> @@ -0,0 +1,200 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +
> +/*
> + * MFD driver for ENE KB3310B embedded controller on Lemote Yeeloong laptops
> + *
> + * Copyright (C) 2008 Lemote Inc.
> + * Author: liujl <liujl@lemote.com>, 2008-04-20
> + *
> + * Copyright (C) 2019 Yifeng Li
> + * Author: Yifeng Li <tomli@tomli.me>


> + * This is a MFD driver for the ENE KB3310B Embedded Controller for Lemote
> + * Yeeloong laptops to provide utility functions to access the chip from
> + * subdrivers, and handle events and interrupts in board files. This is a
> + * special-purpose driver, and it's only used on Lemote Yeeloong laptops,
> + * and is a mandatory dependency.
> + *
> + * NOTE: A regmap could be the reasonable abstraction for I/O, but (1)
> + * it requires some additional refactoring to convert the shutdown/wakeup
> + * routines in board files to subdrivers, and (2) we're only using simple
> + * reads/writes, repmap only adds boilerplates to the existing files without
> + * additional benefits. We simply export the EC-related functions for now,
> + * until we come back to refactor the board files.

Not sure you need either of these comments in the source file.  Add
this stuff to the commit message, if it isn't already and leave it at
that.

> + */
> +
> +#include <linux/export.h>
> +#include <linux/platform_device.h>
> +#include <linux/mfd/core.h>
> +#include <linux/io.h>
> +#include <linux/delay.h>
> +

No need for this space.

> +#include <linux/mfd/yeeloong_kb3310b.h>

Place this with the other headers in alphabetical order please.

> +#ifdef pr_fmt
> +#undef pr_fmt
> +#endif
> +
> +#define DRV_NAME "yeeloong_kb3310b"
> +#define pr_fmt(fmt) DRV_NAME ": " fmt

Remove all of these lines please.

The dev_{dbg,info,warn,err} calls will do all this for you.

> +/*
> + * Most drivers, such as battery or backlight drivers, uses the I/O ports to
> + * access the Index Registers to obtain hardware status and information from
> + * EC chip.
> + */
> +static struct kb3310b_chip *kb3310b_fwinfo;
> +
> +static const struct mfd_cell kb3310b_cells[] = {
> +	{ .name = "yeeloong_sci" },
> +	{ .name = "yeeloong_hwmon" },
> +	{ .name = "yeeloong_battery" },
> +	{ .name = "yeeloong_backlight" },
> +	{ .name = "yeeloong_lcd" },
> +	{ .name = "yeeloong_hotkey" },
> +};
> +
> +static DEFINE_SPINLOCK(kb3310b_index_lock);
> +
> +u8 kb3310b_read(u16 reg)
> +{
> +	unsigned long flags;
> +	u8 val;
> +
> +	spin_lock_irqsave(&kb3310b_index_lock, flags);
> +
> +	outb((reg & 0xff00) >> 8, KB3310B_IO_PORT_HIGH);
> +	outb((reg & 0x00ff), KB3310B_IO_PORT_LOW);
> +	val = inb(KB3310B_IO_PORT_DATA);
> +
> +	spin_unlock_irqrestore(&kb3310b_index_lock, flags);
> +
> +	return val;
> +}
> +EXPORT_SYMBOL_GPL(kb3310b_read);
> +
> +void kb3310b_write(u16 reg, u8 val)
> +{
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&kb3310b_index_lock, flags);
> +
> +	outb((reg & 0xff00) >> 8, KB3310B_IO_PORT_HIGH);
> +	outb((reg & 0x00ff), KB3310B_IO_PORT_LOW);
> +	outb(val, KB3310B_IO_PORT_DATA);
> +	inb(KB3310B_IO_PORT_DATA);  /* flush pending writes */
> +
> +	spin_unlock_irqrestore(&kb3310b_index_lock, flags);
> +}
> +EXPORT_SYMBOL_GPL(kb3310b_write);

I'm afraid that this is not acceptable.  We have APIs to standardise
register handing now, please use those.  I understand that it will
take a little bit of effort to convert this to Regmap, but I think it
would be worth it in the end.

> +bool kb3310b_fw_earlier(char *version)
> +{
> +	return (strncasecmp(kb3310b_fwinfo->version,
> +				version, KB3310B_VERSION_LEN) < 0);
> +}
> +EXPORT_SYMBOL_GPL(kb3310b_fw_earlier);
> +
> +static int kb3310b_probe(struct platform_device *pdev)
> +{
> +	kb3310b_fwinfo = dev_get_platdata(&pdev->dev);
> +	pr_info("firmware version %s", kb3310b_fwinfo->version);

Can the firmware version be read from the device?

> +	return devm_mfd_add_devices(&pdev->dev, -1, kb3310b_cells,
> +				    ARRAY_SIZE(kb3310b_cells), NULL, 0, NULL);
> +}
> +
> +static struct platform_driver kb3310b_driver = {
> +	.driver = {
> +		   .name = "yeeloong_kb3310b",
> +	},
> +	.probe = kb3310b_probe,
> +};
> +builtin_platform_driver(kb3310b_driver);

I would expect this to be at the end of the file.

> +/*
> + * For interrupt handling and power management, the EC chip is also needed to
> + * be queried from the board file at arch/mips/loongson64, through a separate
> + * command port.
> + */
> +
> +/*
> + * This function is used for EC command writes and corresponding status queries.
> + */
> +int kb3310b_query_seq(unsigned char cmd)
> +{
> +	int timeout;
> +	unsigned char status;
> +
> +	static DEFINE_SPINLOCK(kb3310b_command_lock);
> +	unsigned long flags;
> +
> +	spin_lock_irqsave(&kb3310b_command_lock, flags);
> +
> +	/* make chip goto reset mode */
> +	udelay(KB3310B_REG_UDELAY);
> +	outb(cmd, KB3310B_CMD_PORT);
> +	udelay(KB3310B_REG_UDELAY);
> +
> +	/* check if the command is received by EC */
> +	timeout = KB3310B_CMD_TIMEOUT;
> +	status = inb(KB3310B_STS_PORT);
> +	while (timeout-- && (status & (1 << 1))) {
> +		status = inb(KB3310B_STS_PORT);
> +		udelay(KB3310B_REG_UDELAY);
> +	}
> +
> +	spin_unlock_irqrestore(&kb3310b_command_lock, flags);
> +
> +	if (timeout <= 0) {
> +		pr_err("(%x/NA) failed to issue command %d, no response!\n",
> +			timeout, cmd);
> +		return -EINVAL;
> +	}
> +
> +	pr_info("(%x/%x) issued command %d, status: 0x%x\n",
> +		 timeout, KB3310B_CMD_TIMEOUT - timeout,
> +		 cmd, status);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(kb3310b_query_seq);
> +
> +/*
> + * Send query command to EC to get the proper event number.
> + */
> +int kb3310b_query_event_num(void)
> +{
> +	return kb3310b_query_seq(KB3310B_CMD_GET_EVENT_NUM);
> +}
> +EXPORT_SYMBOL_GPL(kb3310b_query_event_num);
> +
> +/*
> + * Get event number from EC.
> + *
> + * NOTE: This routine must follow the query_event_num function in the
> + * interrupt.
> + */
> +int kb3310b_get_event_num(void)
> +{
> +	int timeout = 100;
> +	unsigned char value;
> +	unsigned char status;
> +
> +	udelay(KB3310B_REG_UDELAY);
> +	status = inb(KB3310B_STS_PORT);
> +	udelay(KB3310B_REG_UDELAY);
> +	while (timeout-- && !(status & (1 << 0))) {
> +		status = inb(KB3310B_STS_PORT);
> +		udelay(KB3310B_REG_UDELAY);
> +	}
> +	if (timeout <= 0) {
> +		pr_info("%s: get event number timeout.\n", __func__);
> +		return -EINVAL;
> +	}
> +	value = inb(KB3310B_DAT_PORT);
> +	udelay(KB3310B_REG_UDELAY);
> +
> +	return value;
> +}
> +EXPORT_SYMBOL_GPL(kb3310b_get_event_num);
> diff --git a/include/linux/mfd/yeeloong_kb3310b.h b/include/linux/mfd/yeeloong_kb3310b.h
> new file mode 100644
> index 000000000000..ba8b82153bcd
> --- /dev/null
> +++ b/include/linux/mfd/yeeloong_kb3310b.h
> @@ -0,0 +1,211 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +
> +/*
> + * MFD driver for ENE KB3310B embedded controller on Lemote Yeeloong laptops
> + *
> + * Copyright (C) 2008 Lemote Inc.
> + * Author: liujl <liujl@lemote.com>, 2008-04-20
> + *
> + * Copyright (C) 2019 Yifeng Li
> + * Author: Yifeng Li <tomli@tomli.me>
> + */
> +
> +#ifndef __LINUX_MFD_YEELOONG_KB3310B_H
> +#define __LINUX_MFD_YEELOONG_KB3310B_H
> +
> +extern u8 kb3310b_read(u16 reg);
> +extern void kb3310b_write(u16 reg, u8 val);
> +extern bool kb3310b_fw_earlier(char *version);
> +extern int kb3310b_query_seq(unsigned char cmd);
> +extern int kb3310b_query_event_num(void);
> +extern int kb3310b_get_event_num(void);
> +
> +typedef int (*sci_handler) (int status);
> +
> +extern int yeeloong_sci_register_notify(struct notifier_block *nb);
> +extern int yeeloong_sci_unregister_notify(struct notifier_block *nb);
> +
> +#define KB3310B_VERSION_LEN 8
> +
> +struct kb3310b_chip {
> +	char version[KB3310B_VERSION_LEN];
> +};
> +
> +#define KB3310B_SCI_IRQ_NUM	0x0A
> +
> +/*
> + * The following registers are determined by the EC index configuration.
> + * 1, fill the PORT_HIGH as EC register high part.
> + * 2, fill the PORT_LOW as EC register low part.
> + * 3, fill the PORT_DATA as EC register write data or get the data from it.
> + */
> +#define KB3310B_IO_PORT_HIGH	0x0381
> +#define KB3310B_IO_PORT_LOW	0x0382
> +#define KB3310B_IO_PORT_DATA	0x0383
> +
> +/*
> + * EC delay time is 500us for register and status access
> + */
> +#define KB3310B_REG_UDELAY	500
> +#define KB3310B_CMD_TIMEOUT	0x1000
> +
> +/*
> + * EC access port for SCI communication
> + */
> +#define KB3310B_CMD_PORT		0x66
> +#define KB3310B_STS_PORT		0x66
> +#define KB3310B_DAT_PORT		0x62
> +#define KB3310B_CMD_INIT_IDLE_MODE	0xdd
> +#define KB3310B_CMD_EXIT_IDLE_MODE	0xdf
> +#define KB3310B_CMD_INIT_RESET_MODE	0xd8
> +#define KB3310B_CMD_REBOOT_SYSTEM	0x8c
> +#define KB3310B_CMD_GET_EVENT_NUM	0x84
> +#define KB3310B_CMD_PROGRAM_PIECE	0xda
> +
> +/* temperature & fan registers */
> +#define KB3310B_REG_TEMPERATURE_VALUE	0xF458
> +#define KB3310B_REG_FAN_AUTO_MAN_SWITCH 0xF459
> +#define KB3310B_BIT_FAN_AUTO		0
> +#define KB3310B_BIT_FAN_MANUAL		1
> +#define KB3310B_REG_FAN_CONTROL		0xF4D2
> +#define KB3310B_BIT_FAN_CONTROL_ON	(1 << 0)
> +#define KB3310B_BIT_FAN_CONTROL_OFF	(0 << 0)
> +#define KB3310B_REG_FAN_STATUS		0xF4DA
> +#define KB3310B_BIT_FAN_STATUS_ON	(1 << 0)
> +#define KB3310B_BIT_FAN_STATUS_OFF	(0 << 0)
> +#define KB3310B_REG_FAN_SPEED_HIGH	0xFE22
> +#define KB3310B_REG_FAN_SPEED_LOW	0xFE23
> +#define KB3310B_REG_FAN_SPEED_LEVEL	0xF4CC
> +
> +/* fan speed divider */
> +#define KB3310B_FAN_SPEED_DIVIDER	480000	/* (60*1000*1000/62.5/2)*/
> +
> +/* battery registers */
> +#define KB3310B_REG_BAT_DESIGN_CAP_HIGH		0xF77D
> +#define KB3310B_REG_BAT_DESIGN_CAP_LOW		0xF77E
> +#define KB3310B_REG_BAT_FULLCHG_CAP_HIGH	0xF780
> +#define KB3310B_REG_BAT_FULLCHG_CAP_LOW		0xF781
> +#define KB3310B_REG_BAT_DESIGN_VOL_HIGH		0xF782
> +#define KB3310B_REG_BAT_DESIGN_VOL_LOW		0xF783
> +#define KB3310B_REG_BAT_CURRENT_HIGH		0xF784
> +#define KB3310B_REG_BAT_CURRENT_LOW		0xF785
> +#define KB3310B_REG_BAT_VOLTAGE_HIGH		0xF786
> +#define KB3310B_REG_BAT_VOLTAGE_LOW		0xF787
> +#define KB3310B_REG_BAT_TEMPERATURE_HIGH	0xF788
> +#define KB3310B_REG_BAT_TEMPERATURE_LOW		0xF789
> +#define KB3310B_REG_BAT_RELATIVE_CAP_HIGH	0xF492
> +#define KB3310B_REG_BAT_RELATIVE_CAP_LOW	0xF493
> +#define KB3310B_REG_BAT_VENDOR			0xF4C4
> +#define KB3310B_FLAG_BAT_VENDOR_SANYO		0x01
> +#define KB3310B_FLAG_BAT_VENDOR_SIMPLO		0x02
> +#define KB3310B_REG_BAT_CELL_COUNT		0xF4C6
> +#define KB3310B_FLAG_BAT_CELL_3S1P		0x03
> +#define KB3310B_FLAG_BAT_CELL_3S2P		0x06
> +#define KB3310B_REG_BAT_CHARGE			0xF4A2
> +#define KB3310B_FLAG_BAT_CHARGE_DISCHARGE	0x01
> +#define KB3310B_FLAG_BAT_CHARGE_CHARGE		0x02
> +#define KB3310B_FLAG_BAT_CHARGE_ACPOWER		0x00
> +#define KB3310B_REG_BAT_STATUS			0xF4B0
> +#define KB3310B_BIT_BAT_STATUS_LOW		(1 << 5)
> +#define KB3310B_BIT_BAT_STATUS_DESTROY		(1 << 2)
> +#define KB3310B_BIT_BAT_STATUS_FULL		(1 << 1)
> +#define KB3310B_BIT_BAT_STATUS_IN		(1 << 0)
> +#define KB3310B_REG_BAT_CHARGE_STATUS		0xF4B1
> +#define KB3310B_BIT_BAT_CHARGE_STATUS_OVERTEMP	(1 << 2)
> +#define KB3310B_BIT_BAT_CHARGE_STATUS_PRECHG	(1 << 1)
> +#define KB3310B_REG_BAT_STATE			0xF482
> +#define KB3310B_BIT_BAT_STATE_CHARGING		(1 << 1)
> +#define KB3310B_BIT_BAT_STATE_DISCHARGING	(1 << 0)
> +#define KB3310B_REG_BAT_POWER			0xF440
> +#define KB3310B_BIT_BAT_POWER_S3		(1 << 2)
> +#define KB3310B_BIT_BAT_POWER_ON		(1 << 1)
> +#define KB3310B_BIT_BAT_POWER_ACIN		(1 << 0)
> +
> +/* other registers */
> +
> +/* Audio: rd/wr */
> +#define KB3310B_REG_AUDIO_VOLUME	0xF46C
> +#define KB3310B_REG_AUDIO_MUTE		0xF4E7
> +#define KB3310B_REG_AUDIO_BEEP		0xF4D0
> +
> +/* USB port power or not: rd/wr */
> +#define KB3310B_REG_USB0_FLAG		0xF461
> +#define KB3310B_REG_USB1_FLAG		0xF462
> +#define KB3310B_REG_USB2_FLAG		0xF463
> +#define KB3310B_BIT_USB_FLAG_ON		1
> +#define KB3310B_BIT_USB_FLAG_OFF	0
> +
> +/* LID */
> +#define KB3310B_REG_LID_DETECT		0xF4BD
> +#define KB3310B_BIT_LID_DETECT_ON	1
> +#define KB3310B_BIT_LID_DETECT_OFF	0
> +
> +/* CRT */
> +#define KB3310B_REG_CRT_DETECT		0xF4AD
> +#define KB3310B_BIT_CRT_DETECT_PLUG	1
> +#define KB3310B_BIT_CRT_DETECT_UNPLUG	0
> +
> +/* LCD backlight brightness adjust: 9 levels */
> +#define KB3310B_REG_DISPLAY_BRIGHTNESS	0xF4F5
> +
> +/* Black screen status */
> +#define KB3310B_REG_DISPLAY_LCD		0xF79F
> +#define KB3310B_BIT_DISPLAY_LCD_ON	1
> +#define KB3310B_BIT_DISPLAY_LCD_OFF	0
> +
> +/* LCD backlight control: off/restore */
> +#define KB3310B_REG_BACKLIGHT_CTRL	0xF7BD
> +#define KB3310B_BIT_BACKLIGHT_ON	1
> +#define KB3310B_BIT_BACKLIGHT_OFF	0
> +
> +/* Reset the machine auto-clear: rd/wr */
> +#define KB3310B_REG_RESET		0xF4EC
> +#define KB3310B_BIT_RESET_ON		1
> +
> +/* Light the LED: rd/wr */
> +#define KB3310B_REG_LED			0xF4C8
> +#define KB3310B_BIT_LED_RED_POWER	(1 << 0)
> +#define KB3310B_BIT_LED_ORANGE_POWER	(1 << 1)
> +#define KB3310B_BIT_LED_GREEN_CHARGE	(1 << 2)
> +#define KB3310B_BIT_LED_RED_CHARGE	(1 << 3)
> +#define KB3310B_BIT_LED_NUMLOCK		(1 << 4)
> +
> +/* Test LED mode, all LED on/off */
> +#define KB3310B_REG_LED_TEST		0xF4C2
> +#define KB3310B_BIT_LED_TEST_IN		1
> +#define KB3310B_BIT_LED_TEST_OUT	0
> +
> +/* Camera on/off */
> +#define KB3310B_REG_CAMERA_STATUS	0xF46A
> +#define KB3310B_BIT_CAMERA_STATUS_ON	1
> +#define KB3310B_BIT_CAMERA_STATUS_OFF	0
> +#define KB3310B_REG_CAMERA_CONTROL	0xF7B7
> +#define KB3310B_BIT_CAMERA_CONTROL_OFF	0
> +#define KB3310B_BIT_CAMERA_CONTROL_ON	1
> +
> +/* WLAN Status */
> +#define KB3310B_REG_WLAN		0xF4FA
> +#define KB3310B_BIT_WLAN_ON		1
> +#define KB3310B_BIT_WLAN_OFF		0
> +
> +/* SCI Event Number from EC */
> +enum {
> +	KB3310B_EVENT_START = 0x22,
> +	KB3310B_EVENT_LID = 0x23,	   /* LID open/close */
> +	KB3310B_EVENT_DISPLAY_TOGGLE,	   /* Fn+F3 for display switch */
> +	KB3310B_EVENT_SLEEP,		   /* Fn+F1 for entering sleep mode */
> +	KB3310B_EVENT_OVERTEMP,		   /* Over-temperature occurred */
> +	KB3310B_EVENT_CRT_DETECT,	   /* CRT is connected */
> +	KB3310B_EVENT_CAMERA,		   /* Camera on/off */
> +	KB3310B_EVENT_USB_OC2,		   /* USB2 Overcurrent occurred */
> +	KB3310B_EVENT_USB_OC0,		   /* USB0 Overcurrent occurred */
> +	KB3310B_EVENT_BLACK_SCREEN,	   /* Turn on/off backlight */
> +	KB3310B_EVENT_AUDIO_MUTE,	   /* Mute on/off */
> +	KB3310B_EVENT_DISPLAY_BRIGHTNESS,  /* LCD backlight brightness adjust */
> +	KB3310B_EVENT_AC_BAT,		   /* AC & Battery relative issue */
> +	KB3310B_EVENT_AUDIO_VOLUME,	   /* Volume adjust */
> +	KB3310B_EVENT_WLAN,		   /* WLAN on/off */
> +	KB3310B_EVENT_END
> +};
> +
> +#endif /* !__LINUX_MFD_YEELOONG_KB3310B_H */

-- 
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/1] mfd: yeeloong_kb3310b: support KB3310B EC for Lemote Yeeloong laptops.
  2019-03-30  8:18 ` [PATCH 1/1] mfd: yeeloong_kb3310b: support KB3310B EC " Tom Li
  2019-04-03  8:36   ` Lee Jones
@ 2020-01-23  0:22   ` Matt Turner
  1 sibling, 0 replies; 4+ messages in thread
From: Matt Turner @ 2020-01-23  0:22 UTC (permalink / raw)
  To: Tom Li; +Cc: Lee Jones, linux-mips, Paul Burton, LKML, Yifeng Li

On Sat, Mar 30, 2019 at 1:19 AM Tom Li <biergaizi2009@gmail.com> wrote:
>
> From: Yifeng Li <tomli@tomli.me>
>
> Lemote Yeeloong is a laptop powered by Loongson 2F MIPS processor,
> primarily a demo platform for hobbyists and developers. It uses an
> ENE KB3310B Embedded Controller with customized firmware to implement
> hardware and power management.
>
> A monolithic platform driver code for those functionality has existed
> out-of-tree for many years. This commit creates a MFD driver for the EC
> chip on Yeeloong laptop to isolate EC-related code from core MIPS code,
> and serves as the foundation of various subdrivers.
>
> NOTE: A regmap could be the reasonable abstraction for I/O, but (1)
> it requires some additional refactoring to convert the shutdown/wakeup
> routines in board files to subdrivers, and (2) we're only using simple
> reads/writes, repmap only adds boilerplates to the existing files without
> additional benefits. We simply export the EC-related functions for now,
> until we come back to refactor the board files.
>
> Signed-off-by: Yifeng Li <tomli@tomli.me>

Did you give up on upstreaming this code? That would be a shame, and
somewhat ironic given that you were frustrated about lack of review,
etc, and then never responded to the review given :(

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-01-23  0:23 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-30  8:18 [PATCH 0/1] KB3310B MFD Driver for Lemote Yeeloong laptops Tom Li
2019-03-30  8:18 ` [PATCH 1/1] mfd: yeeloong_kb3310b: support KB3310B EC " Tom Li
2019-04-03  8:36   ` Lee Jones
2020-01-23  0:22   ` Matt Turner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).