From nobody Sun Feb 8 06:44:33 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6916CEE14D3 for ; Thu, 7 Sep 2023 03:14:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237668AbjIGDOG (ORCPT ); Wed, 6 Sep 2023 23:14:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55932 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231859AbjIGDOC (ORCPT ); Wed, 6 Sep 2023 23:14:02 -0400 Received: from mail-pf1-x435.google.com (mail-pf1-x435.google.com [IPv6:2607:f8b0:4864:20::435]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E69D810CA for ; Wed, 6 Sep 2023 20:13:54 -0700 (PDT) Received: by mail-pf1-x435.google.com with SMTP id d2e1a72fcca58-68a42d06d02so459498b3a.0 for ; Wed, 06 Sep 2023 20:13:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1694056434; x=1694661234; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=CweUPJL5xZp7oHDLbCdTD5dawMh3eCK/C8GrYfBGMCg=; b=qN0a++KZHBr+sVJix91vyJ2s4vMbc0d4bdzT3J00KyV3s6jugHls+O2z3ZsbQWwcxs 0Xl3mXyQhTz+5tePPbMoXcz/4TbR0Z+kRSOwkq8YmGIAb2L+xz6O8wHgoHrkPDNG3ZZ2 ZQCObYis/cywvYueWLXEVOAbsJknl49qBqcHr1rei5UfM5XRra3eO38RsQ0iUCFWK7qb /AGYKcUdVXJXQ95nq59Ppy08ujAk/bPWjLtXPihj4HGAb+w+LyuQSUqySzwn/fjv9Cwp +CLrLr7MkCLYK8ncYd0nJ3Qnekzx/XWGfcNbYJ2zZR80neVa681tRgFXV/8Fd+yxsH0y U5IQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1694056434; x=1694661234; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=CweUPJL5xZp7oHDLbCdTD5dawMh3eCK/C8GrYfBGMCg=; b=lL0HRwKVS8lESQ5BotGcrFBzJsI+ij95Ojdi0R8rVBmsox0lGOsRkzar8Czg0NqrSZ NIo+8sxysJfMpObaDGoWatPxnKj/FQJXi4Q7lsQfiPVQIofXQeyzAuo6UG/5MaTDukYT DecpltsrIvHNuMG8rFYeIP6UFckvfpIn5boYCIVw9zVsAsiJFUfk9rzKaLvz67gEFRi+ a0Ya42y8F9Po+vjACQS7jb0g4Zy+3VOB+QZpgRhuYfdys3x1dWA+S9MMR2eR51j1VxNv ZuQqz8DvJ63yzcf7cqsX0MCWmuEk9NPsLeCTqvdson5xmpz2oHsmy9kSG4lnraj4hKvy pKEA== X-Gm-Message-State: AOJu0YwhlX5F7twMR6QlYW+oajYuyXLJnGuj9t/exZD/zQQJm42CbQQl Nuz+9GCbUBsnbCUfChTgWQyjtdCqNew= X-Google-Smtp-Source: AGHT+IEv25aOYkrH42w0Sz/YQbI/4HwNCkvmTUNVzZDeFV88oGcjNjaefx6ornLdu89dHPXko2bUAA== X-Received: by 2002:a05:6a20:9744:b0:14d:446f:7211 with SMTP id hs4-20020a056a20974400b0014d446f7211mr16211714pzc.53.1694056433896; Wed, 06 Sep 2023 20:13:53 -0700 (PDT) Received: from wenkaidev (118-163-147-182.hinet-ip.hinet.net. [118.163.147.182]) by smtp.gmail.com with ESMTPSA id o9-20020a170902bcc900b001c1f4edfb87sm11680361pls.92.2023.09.06.20.13.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Sep 2023 20:13:53 -0700 (PDT) From: advantech.susiteam@gmail.com To: advantech.susiteam@gmail.com Cc: wenkai.chung@advantech.com.tw, Susi.Driver@advantech.com, Lee Jones , linux-kernel@vger.kernel.org Subject: [PATCH 1/4] mfd: eiois200: Insert EIO-IS200 core driver to Kconfig Date: Thu, 7 Sep 2023 11:13:15 +0800 Message-Id: <20230907031320.6814-2-advantech.susiteam@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230907031320.6814-1-advantech.susiteam@gmail.com> References: <20230907031320.6814-1-advantech.susiteam@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Wenkai This patch adds support for the Advantech EIO-IS200 Embedded Controller core driver to the Kconfig configuration menu. When configuring the kernel using tools like menuconfig, you can select M to build it as a module or select N to exclude it from being built-in. Signed-off-by: Wenkai --- drivers/mfd/Kconfig | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index aea95745c73f..85bcb8f95501 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -52,6 +52,23 @@ config MFD_ACT8945A linear regulators, along with a complete ActivePath battery charger. =20 + config MFD_EIOIS200 + tristate "Advantech EIO-IS200 Embedded Controller core driver" + depends on X86 + depends on m + default m + select MFD_CORE + select REGMAP_MMIO + help + This driver provides support for the Advantech EIO-IS200 EC and + activate its sub-drivers, including GPIO, watchdog, hardware + monitor, I2C, and thermal. + + This driver option only has two states: M and N. It cannot be + built-in. To compile this driver as a module, choose M here; the + module will be called eiois200_core. The system will force it to + M if any one of its sub-drivers is chosen. + config MFD_SUN4I_GPADC tristate "Allwinner sunxi platforms' GPADC MFD driver" select MFD_CORE --=20 2.34.1 From nobody Sun Feb 8 06:44:33 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 891CBEE14A9 for ; Thu, 7 Sep 2023 03:14:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237521AbjIGDOK (ORCPT ); Wed, 6 Sep 2023 23:14:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52932 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238038AbjIGDOD (ORCPT ); Wed, 6 Sep 2023 23:14:03 -0400 Received: from mail-pl1-x633.google.com (mail-pl1-x633.google.com [IPv6:2607:f8b0:4864:20::633]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9D9DF10F1 for ; Wed, 6 Sep 2023 20:13:58 -0700 (PDT) Received: by mail-pl1-x633.google.com with SMTP id d9443c01a7336-1bf11b1c7d0so11821585ad.0 for ; Wed, 06 Sep 2023 20:13:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1694056437; x=1694661237; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=+DTEliymHGGsjHkf9gOQvp04Ee/X7GkoMiapI3zHqYg=; b=Cw9YURglDcaFDIW2Ze25FDZcDgLOOu0iHKVXwxawE0HzVR/9k2oupphQNxX0V/d/Q9 QTbRpnJn/P7jcQdoQx/Na2g9ZzvzJDEHpaqFfcYv7dCSVBDyFM8JQ+Ul2SbMpexcgIsc DOxBbQQvJ4E1n0f0HkIJn0wFJhLCycPqY8QjjUjhYmzAqWedxqRwWol36elzQDj5e8+6 mV8haMkrgsI9R8SrY1ZIENN+QvqWIT9dXEiFml9RWbwOG8dQeVxNPtbnB+TmVk7YOh9S VU7GET/1YFCAtGGvOhTj7M/uc8fGeIMjuoTkdGXEXQePS7JZz3+x36LQy6AL4tOs9TEb Mz0A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1694056437; x=1694661237; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+DTEliymHGGsjHkf9gOQvp04Ee/X7GkoMiapI3zHqYg=; b=kfwn+LvPgX2/GhEVJPKaGZ4yNDV+u90acL2QDY0VNHM1XXua1O9+okVC97kJd1TkXi m4+cPlev9QpQKzVCCnEO5K6lW6apZaI6QYhB8R3UmjbHfVCGCGixQ1p6hy9K2oVzRYSo SXBJatKMjMI6WTnfDP8c57bNbZvMez3lzbpHuh0U8STGjFJa70cvxp+Yq8ck8FVrnKWE k5od2NE+iFK5zFAfFnrEo9EDxdeJ3xbz4gBmn+kOpjpY7pYiRZxnvbgJciIUWnFE6WSa n9YjyrWi+8+r/hQghlFfuUW0Ei1wUG4dnIlt49bS2z0KHsa+3ECj8PQJGyZB4sddmUGl Izww== X-Gm-Message-State: AOJu0Yw8VjFtwgJ+EzW5NMoPxUIVZsXSYdU0TjC9Sn1Q86Rpza8Wz8Qf 3JAP4fe7v9BOYktjziPpTfkM9A49xKc= X-Google-Smtp-Source: AGHT+IH1GNIj5KngpiOl6YqNBSSwIdokF8UAu4o0Ra+cs7LfoXmoEGGWWjFmc55EspggbPXfFY2jlQ== X-Received: by 2002:a17:902:e54e:b0:1c0:bcbc:d67 with SMTP id n14-20020a170902e54e00b001c0bcbc0d67mr1716353plf.22.1694056437641; Wed, 06 Sep 2023 20:13:57 -0700 (PDT) Received: from wenkaidev (118-163-147-182.hinet-ip.hinet.net. [118.163.147.182]) by smtp.gmail.com with ESMTPSA id j1-20020a170902c3c100b001bb9aadfb04sm11609943plj.220.2023.09.06.20.13.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Sep 2023 20:13:57 -0700 (PDT) From: advantech.susiteam@gmail.com To: advantech.susiteam@gmail.com Cc: wenkai.chung@advantech.com.tw, Susi.Driver@advantech.com, Lee Jones , linux-kernel@vger.kernel.org Subject: [PATCH 2/4] mfd: eiois200: Insert EIO-IS200 core driver to Makefile Date: Thu, 7 Sep 2023 11:13:16 +0800 Message-Id: <20230907031320.6814-3-advantech.susiteam@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230907031320.6814-1-advantech.susiteam@gmail.com> References: <20230907031320.6814-1-advantech.susiteam@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Wenkai This patch adds support for the Advantech EIO-IS200 Embedded Controller core driver to the Makefile in the drivers/mfd directory. Signed-off-by: Wenkai --- drivers/mfd/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index c66f07edcd0e..46dc303ddae4 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_MFD_CROS_EC_DEV) +=3D cros_ec_dev.o obj-$(CONFIG_MFD_CS42L43) +=3D cs42l43.o obj-$(CONFIG_MFD_CS42L43_I2C) +=3D cs42l43-i2c.o obj-$(CONFIG_MFD_CS42L43_SDW) +=3D cs42l43-sdw.o +obj-$(CONFIG_MFD_EIOIS200) +=3D eiois200_core.o obj-$(CONFIG_MFD_ENE_KB3930) +=3D ene-kb3930.o obj-$(CONFIG_MFD_EXYNOS_LPASS) +=3D exynos-lpass.o obj-$(CONFIG_MFD_GATEWORKS_GSC) +=3D gateworks-gsc.o --=20 2.34.1 From nobody Sun Feb 8 06:44:33 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3643AEE14D3 for ; Thu, 7 Sep 2023 03:14:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240245AbjIGDOP (ORCPT ); Wed, 6 Sep 2023 23:14:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53100 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238961AbjIGDOJ (ORCPT ); Wed, 6 Sep 2023 23:14:09 -0400 Received: from mail-qt1-x834.google.com (mail-qt1-x834.google.com [IPv6:2607:f8b0:4864:20::834]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 77BBD199F for ; Wed, 6 Sep 2023 20:14:03 -0700 (PDT) Received: by mail-qt1-x834.google.com with SMTP id d75a77b69052e-410af8f75d9so3900911cf.0 for ; Wed, 06 Sep 2023 20:14:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1694056442; x=1694661242; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Wnd0I07HeUzU7voJTdtOIpPdlBHbTA3K5Yawn0w0tak=; b=V+Kfj2oRDlAh19IMEtsI8lHnjqgOnEp8kFncEImVpeDXWlE7sAKCegtIiOEdoxEMvy KqcB49iOn6LADsG2U/FM0FYxAwajWzD5AM3HuUF8yKRbdFrfKPD+mwhYnlJjgZmQkBWU xiJ6bRUFG2xRyNpWDfoNb1gONUE13qkvBlrL4UIa0r/ChfDY/J//vBlIvDco+3NsqOym CstkvDi2+1hhlwHvflihQzCVgsh5Uno9F6B/yjUTRpG8SAMGppEWDDqn2SWdDEAsqHeX AlWxP8FtIvn5NQawqAjBIaSCUDkPHHYIdC/8CweDI/M8YaNOc2XifAYafTfkM3nGAP0L 7W2w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1694056442; x=1694661242; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Wnd0I07HeUzU7voJTdtOIpPdlBHbTA3K5Yawn0w0tak=; b=Ocih9jsxc3743PYvBhK42FP+lVJRsVYh+eri3sms9+g1+e0W8cM7l9htRpEUWiPutG 48ZWEFolqDwMVG6pwyyt0lqT4uU5usOH5ZwqrP9qMzmzezr++aE/miX6NmKTjLW8Kiky iEFIkawowRunWO4ymuGt3Q7HDSWSapMaCPOLDggUDDuBVE0N9CN/wumYRYT04O8RRgFA /72NRtDuzwBdEECBHdSnjKAO3MBxmN645obxWZAOk9UrkIQVg46At12JJQsU9awpxfoy c7686qEOKLJFdGpF1JdbRgIjEANRGF7ThXhRiNiVIpMlB279AUeNMxQdRB5XRnWarMkx d4nQ== X-Gm-Message-State: AOJu0Yx0lNvlyNzsBr0gcsIVYLE2pPIKP+OLKY+CzCTrW023s66CgiJV pCGfMAgoawJrzYlK4Z+O+uFzbuTL1mI= X-Google-Smtp-Source: AGHT+IHE1ERuyx584zsNLMcMObFde+LaJmcvYYXzLS4XLUFyxpCorEdm+r4kUS3JbvPlIyeA+JswNw== X-Received: by 2002:a05:620a:4012:b0:76e:ef94:127f with SMTP id h18-20020a05620a401200b0076eef94127fmr27425551qko.56.1694056442087; Wed, 06 Sep 2023 20:14:02 -0700 (PDT) Received: from wenkaidev ([123.51.235.123]) by smtp.gmail.com with ESMTPSA id e4-20020aa78c44000000b0068be216b091sm11455269pfd.24.2023.09.06.20.14.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Sep 2023 20:14:01 -0700 (PDT) From: advantech.susiteam@gmail.com To: advantech.susiteam@gmail.com Cc: wenkai.chung@advantech.com.tw, Susi.Driver@advantech.com, Lee Jones , linux-kernel@vger.kernel.org Subject: [PATCH 3/4] mfd: eiois200: Add Header for EIO-IS200 Core Driver Date: Thu, 7 Sep 2023 11:13:17 +0800 Message-Id: <20230907031320.6814-4-advantech.susiteam@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230907031320.6814-1-advantech.susiteam@gmail.com> References: <20230907031320.6814-1-advantech.susiteam@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Wenkai This patch adds the header file necessary for the Advantech EIO-IS200 Core Driver. This header file provides the required definitions and structures for communicating with the EIO-IS200 EC and its various functionalities. Signed-off-by: Wenkai --- drivers/mfd/eiois200.h | 137 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 drivers/mfd/eiois200.h diff --git a/drivers/mfd/eiois200.h b/drivers/mfd/eiois200.h new file mode 100644 index 000000000000..d4c3f917811c --- /dev/null +++ b/drivers/mfd/eiois200.h @@ -0,0 +1,137 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Header for the Advantech EIO-IS200 core driver and its sub-drivers + * + * Copyright (C) 2023 Advantech Co., Ltd. + * Author: wenkai.chung + */ + +#ifndef _MFD_EIOIS200_H_ +#define _MFD_EIOIS200_H_ +#include +#include + +/* Definition */ +#define EIOIS200_CHIPID1 0x20 +#define EIOIS200_CHIPID2 0x21 +#define EIOIS200_CHIPVER 0x22 +#define EIOIS200_SIOCTRL 0x23 +#define EIOIS200_SIOCTRL_SIOEN BIT(0) +#define EIOIS200_SIOCTRL_SWRST BIT(1) +#define EIOIS200_IRQCTRL 0x70 +#define EIOIS200_CHIPID 0x9610 +#define EIO201_211_CHIPID 0x9620 +#define EIOIS200_ICCODE 0x10 +#define EIO201_ICCODE 0x20 +#define EIO211_ICCODE 0x21 + +/* LPC PNP */ +#define EIOIS200_PNP_INDEX 0x299 +#define EIOIS200_PNP_DATA 0x29A +#define EIOIS200_SUB_PNP_INDEX 0x499 +#define EIOIS200_SUB_PNP_DATA 0x49A +#define EIOIS200_EXT_MODE_ENTER 0x87 +#define EIOIS200_EXT_MODE_EXIT 0xAA + +/* LPC LDN */ +#define EIOIS200_LDN 0x07 +#define EIOIS200_LDN_PMC0 0x0C +#define EIOIS200_LDN_PMC1 0x0D + +/* PMC registers */ +#define EIOIS200_PMC_PORT 0x2F0 +#define EIOIS200_PMC_PORT_SUB 0x60 +#define EIOIS200_PMC_STATUS_IBF BIT(1) +#define EIOIS200_PMC_STATUS_OBF BIT(0) +#define EIOIS200_LDAR 0x30 +#define EIOIS200_LDAR_LDACT BIT(0) +#define EIOIS200_IOBA0H 0x60 +#define EIOIS200_IOBA0L 0x61 +#define EIOIS200_IOBA1H 0x62 +#define EIOIS200_IOBA1L 0x63 + +/* PMC command list */ +#define EIOIS200_PMC_CMD_ACPIRAM_READ 0x31 +#define EIOIS200_PMC_CMD_CFG_SAVE 0x56 + +/* OLD PMC */ +#define EIOIS200_PMC_NO_INDEX 0xFF + +/* ACPI RAM Address Table */ +#define EIOIS200_ACPIRAM_VERSIONSECTION (0xFA) +#define EIOIS200_ACPIRAM_ICVENDOR (EIOIS200_ACPIRAM_VERSIONSECTION + 0x00) +#define EIOIS200_ACPIRAM_ICCODE (EIOIS200_ACPIRAM_VERSIONSECTION + 0x01) +#define EIOIS200_ACPIRAM_CODEBASE (EIOIS200_ACPIRAM_VERSIONSECTION + 0x02) + +/* Firmware */ +#define EIOIS200_F_SUB_NEW_CODE_BASE BIT(6) +#define EIOIS200_F_SUB_CHANGED BIT(7) +#define EIOIS200_F_NEW_CODE_BASE BIT(8) +#define EIOIS200_F_CHANGED BIT(9) +#define EIOIS200_F_SUB_CHIP_EXIST BIT(30) +#define EIOIS200_F_CHIP_EXIST BIT(31) + +/* Others */ +#define EC_NUM 2 + +struct _pmc_port { + union { + u16 cmd; + u16 status; + }; + u16 data; +}; + +struct _pmc_op { + u8 cmd; + u8 control; + u8 device_id; + u8 size; + u8 *payload; + u8 chip; + u16 timeout; +}; + +enum eiois200_rw_operation { + OPERATION_READ, + OPERATION_WRITE, +}; + +struct eiois200_dev { + u32 flag; + + struct _pmc_port pmc[2]; + + struct mutex mutex; /* Protects PMC command access */ +}; + +/** + * eiois200_core_pmc_operation - Execute a new pmc command + * @op: Pointer to an new pmc command. + */ +int eiois200_core_pmc_operation(struct _pmc_op *operation); + +enum eiois200_pmc_wait { + PMC_WAIT_INPUT, + PMC_WAIT_OUTPUT, +}; + +/** + * eiois200_core_pmc_wait - Wait for input / output buffer to be ready + * @id: 0 for main chip, 1 for sub chip. + * @wait: %PMC_WAIT_INPUT or %PMC_WAIT_OUTPUT. + * %PMC_WAIT_INPUT for waiting input buffer data ready. + * %PMC_WAIT_OUTPUT for waiting output buffer empty. + * @timeout: The timeout value. + */ +int eiois200_core_pmc_wait(int id, enum eiois200_pmc_wait wait, uint timeo= ut); + +#define WAIT_IBF(id, timeout) eiois200_core_pmc_wait(id, PMC_WAIT_INPUT, t= imeout) +#define WAIT_OBF(id, timeout) eiois200_core_pmc_wait(id, PMC_WAIT_OUTPUT, = timeout) + +#ifdef pr_fmt +#undef pr_fmt +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#endif + +#endif --=20 2.34.1 From nobody Sun Feb 8 06:44:33 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 643BDEE14D3 for ; Thu, 7 Sep 2023 03:14:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240287AbjIGDOS (ORCPT ); Wed, 6 Sep 2023 23:14:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41994 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241603AbjIGDOQ (ORCPT ); Wed, 6 Sep 2023 23:14:16 -0400 Received: from mail-pf1-x42d.google.com (mail-pf1-x42d.google.com [IPv6:2607:f8b0:4864:20::42d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4F1881BD4 for ; Wed, 6 Sep 2023 20:14:07 -0700 (PDT) Received: by mail-pf1-x42d.google.com with SMTP id d2e1a72fcca58-68a41031768so427898b3a.3 for ; Wed, 06 Sep 2023 20:14:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1694056446; x=1694661246; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=SWMrqCy7R+G/723LkSfL+R0pmpIo3S3bNAzLVn5pg6g=; b=qK6CMikC1J7W5ByHOTidYaVzCPQN9xJY1b9jZcTVB7JqZlu4E9ddGXtpXfUH0lNVTA VNsrJNy8ZWXRBeoUgHgKht5NzoYx263fxUOtYM1fKvC2JGqZkkB79oVRqkIv3exkFpQU cMJFd+AlNMCdqnHzXvgQfSJZKT18ku7MXauGTNHwnE2FI8kxCQ/o1hvz9AcfZYy5zYnh pQDSdiPXaX0DmKnO8HbyQzLOcUZT9c46Aya/aWR3WPO1Hb7Q8gUCU9dtdw7K0Tn3WeRq vzNFamoWD1sWR86bu8WpRNmln9qCf4dMQpATXDl44Rr4eVjFC4XG2DaoFSM1dcXZFi0B VF3A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1694056446; x=1694661246; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=SWMrqCy7R+G/723LkSfL+R0pmpIo3S3bNAzLVn5pg6g=; b=k/qlCuLtA8BY4mh9UzgIUDALT1mD+T53f5t2aeQaGrPmF4vVY8lxEhdf74dhORTkU1 dITHOstgS1do/9CiAUma8CekJ/ibv3932RrHEsV5R+kr7oMIrqeh1/Naa//Aqw5x9Hn/ YzEJpe4rEF+qvIVgQnB/zxKgkgZUC1eCcr7ios4XDKfAN55yIiU8VEp8ZHJt4rM3bv+T Y3cOqwBYUFh+2aC1o94ObwIbERz5O61/A7HrQ0Nq11SqvJ4v//O1d3LFUK1KHOnlMsdd 94VsGJh29FIQrxktliYCj4sVS4dv+l79Vs8HJYd8H+nbw9IIlKPrT15CFfMs/DEdrv8t 3Wug== X-Gm-Message-State: AOJu0YzYIk/Glv4AwZm5SqiLTcQ0ccQ1zao2+VRtIUbKSDuQ3eakdTvc KI0KmBdQq0Avvm0a3O5X8Zk0BkTjTEc= X-Google-Smtp-Source: AGHT+IFPpNnQm6m7jXbyjpaO9PmGv7FvfwK6Pi/dr7EhomAh2IeqmmKT1lDyrL/XuIdMz2l7TLDZkQ== X-Received: by 2002:a05:6a20:f398:b0:148:1185:8802 with SMTP id qr24-20020a056a20f39800b0014811858802mr14606135pzb.30.1694056445995; Wed, 06 Sep 2023 20:14:05 -0700 (PDT) Received: from wenkaidev (118-163-147-182.hinet-ip.hinet.net. [118.163.147.182]) by smtp.gmail.com with ESMTPSA id q15-20020a62e10f000000b00687ce7c6540sm11836047pfh.99.2023.09.06.20.14.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 06 Sep 2023 20:14:05 -0700 (PDT) From: advantech.susiteam@gmail.com To: advantech.susiteam@gmail.com Cc: wenkai.chung@advantech.com.tw, Susi.Driver@advantech.com, Lee Jones , linux-kernel@vger.kernel.org Subject: [PATCH 4/4] mfd: eiois200: Add EIO-IS200 Series EC Core Driver Date: Thu, 7 Sep 2023 11:13:18 +0800 Message-Id: <20230907031320.6814-5-advantech.susiteam@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230907031320.6814-1-advantech.susiteam@gmail.com> References: <20230907031320.6814-1-advantech.susiteam@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Wenkai This patch introduces the Advantech EIO-IS200 Series EC Core Driver. The EIO-IS200 combines hardware functionality with firmware capabilities to provide key features through a dedicated Power Management Channel (PMC). Key Features: - Implements the core EIO-IS200 IC driver that serves as the interface to the IC's firmware and hardware functions. - Contains low-level functions for accessing the IC's Power Management Channel (PMC). - Manages PMC command execution, PMC buffer handling, and communication. - Expose a regmap and a mutex for low-level access. - Activates support for GPIO, I2C, Hwmon, and Watchdog functionalities of the EIO-IS200 IC. - Provides various sysfs attributes to expose information about the EC chip, firmware, and motherboard. - Includes a timeout parameter to allow modification of the default PMC command timeout value, which is particularly useful when dealing with an extremely slow-responding device. Signed-off-by: Wenkai --- drivers/mfd/eiois200_core.c | 590 ++++++++++++++++++++++++++++++++++++ 1 file changed, 590 insertions(+) create mode 100644 drivers/mfd/eiois200_core.c diff --git a/drivers/mfd/eiois200_core.c b/drivers/mfd/eiois200_core.c new file mode 100644 index 000000000000..7459dee1ed53 --- /dev/null +++ b/drivers/mfd/eiois200_core.c @@ -0,0 +1,590 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Advantech EIO-IS200 Series EC base Driver + * + * This driver provides an interface to access the EIO-IS200 Series EC + * firmware via its own Power Management Channel (PMC) for subdrivers: + * + * - Watchdog: drivers/watchdog/eiois200_wdt + * - GPIO: drivers/gpio/gpio_eiois200 + * - Hwmon: drivers/hwmon/eiois200_hwmon + * - I2C: drivers/i2c/busses/i2c_eiois200 + * - Thermal: drivers/thermal/eiois200_thermal + * + * A system may have one or two independent EIO-IS200s. + * + * Copyright (C) 2023 Advantech Co., Ltd. + * Author: wenkai.chung + */ + +#include +#include +#include +#include +#include +#include + +#include "eiois200.h" + +#define TIMEOUT_MAX (10 * 1000 * 1000) +#define TIMEOUT_MIN 200 + +static uint timeout =3D 5000; +module_param(timeout, uint, 0664); +MODULE_PARM_DESC(timeout, + "Default PMC command timeout in usec.\n"); + +struct eiois200_dev_port { + u16 idx; + u16 data; +}; + +struct eiois200_dev_port pnp_port[] =3D { + { .idx =3D EIOIS200_PNP_INDEX, .data =3D EIOIS200_PNP_DATA }, + { .idx =3D EIOIS200_SUB_PNP_INDEX, .data =3D EIOIS200_SUB_PNP_DATA }, +}; + +static struct eiois200_dev *eiois200_dev; +static struct regmap *regmap_is200; + +static struct mfd_cell susi_mfd_devs[] =3D { + { .name =3D "eiois200_wdt" }, + { .name =3D "gpio_eiois200" }, + { .name =3D "eiois200_hwmon" }, + { .name =3D "eiois200_i2c" }, + { .name =3D "eiois200_thermal" }, +}; + +struct regmap_range is200_range[] =3D { + regmap_reg_range(EIOIS200_PNP_INDEX, EIOIS200_PNP_DATA), + regmap_reg_range(EIOIS200_SUB_PNP_INDEX, EIOIS200_SUB_PNP_DATA), + regmap_reg_range(EIOIS200_PMC_PORT, EIOIS200_PMC_PORT + 0x0F), + regmap_reg_range(EIOIS200_PMC_PORT_SUB, EIOIS200_PMC_PORT_SUB + 0x0F), +}; + +static const struct regmap_access_table volatile_regs =3D { + .yes_ranges =3D is200_range, + .n_yes_ranges =3D ARRAY_SIZE(is200_range), +}; + +static const struct regmap_config pnp_regmap_config =3D { + .name =3D "eiois200-gpio", + .reg_bits =3D 16, + .val_bits =3D 8, + .volatile_table =3D &volatile_regs, + .io_port =3D true, +}; + +/* Following are EIO-IS200 pnp io port access functions */ +static int is200_pnp_read(struct eiois200_dev_port *port, u8 idx) +{ + int val; + + if (regmap_write(regmap_is200, port->idx, idx)) + pr_err("Error port write 0x%X\n", port->idx); + + if (regmap_read(regmap_is200, port->data, &val)) + pr_err("Error port read 0x%X\n", port->data); + + return val; +} + +static void is200_pnp_write(struct eiois200_dev_port *port, u8 idx, u8 dat= a) +{ + if (regmap_write(regmap_is200, port->idx, idx) || + regmap_write(regmap_is200, port->data, data)) + pr_err("Error port write 0x%X %X\n", + port->idx, port->data); +} + +static void is200_pnp_enter(struct eiois200_dev_port *port) +{ + if (regmap_write(regmap_is200, port->idx, EIOIS200_EXT_MODE_ENTER) || + regmap_write(regmap_is200, port->idx, EIOIS200_EXT_MODE_ENTER)) + pr_err("Error port write 0x%X\n", port->idx); +} + +static void is200_pnp_leave(struct eiois200_dev_port *port) +{ + if (regmap_write(regmap_is200, port->idx, EIOIS200_EXT_MODE_EXIT)) + pr_err("Error port write 0x%X\n", port->idx); +} + +/* Following are EIO-IS200 io port access functions for pmc command */ +static int pmc_write_data(int id, u8 value, u16 timeout) +{ + int ret; + + if (WAIT_IBF(id, timeout)) + return -ETIME; + + ret =3D regmap_write(regmap_is200, eiois200_dev->pmc[id].data, value); + if (ret) + pr_err("Error pmc write %X:%X\n", + eiois200_dev->pmc[id].data, value); + + return ret; +} + +static int pmc_write_cmd(int id, u8 value, u16 timeout) +{ + int ret; + + if (WAIT_IBF(id, timeout)) + return -ETIME; + + ret =3D regmap_write(regmap_is200, eiois200_dev->pmc[id].cmd, value); + if (ret) + pr_err("Error pmc write %X:%X\n", + eiois200_dev->pmc[id].data, value); + + return ret; +} + +static int pmc_read_data(int id, u8 *value, u16 timeout) +{ + int val, ret; + + if (WAIT_OBF(id, timeout)) + return -ETIME; + + ret =3D regmap_read(regmap_is200, eiois200_dev->pmc[id].data, &val); + if (ret) + pr_err("Error pmc read %X\n", eiois200_dev->pmc[id].data); + else + *value =3D val & 0xFF; + + return ret; +} + +static int pmc_read_status(int id) +{ + int val; + + if (regmap_read(regmap_is200, eiois200_dev->pmc[id].data, &val)) { + pr_err("Error pmc read %X\n", eiois200_dev->pmc[id].data); + return 0; + } + + return val; +} + +static void pmc_clear(int id) +{ + int val; + + /* Check if input buffer blocked */ + if ((pmc_read_status(id) & EIOIS200_PMC_STATUS_IBF) =3D=3D 0) + return; + + /* Read out previous garbage */ + if (regmap_read(regmap_is200, eiois200_dev->pmc[id].data, &val)) + pr_err("Error pmc clear\n"); + + usleep_range(10, 100); +} + +/** + * eiois200_core_pmc_wait - Wait for input / output buffer to be ready. + * @id: 0 for main chip, 1 for sub chip. + * @wait: %PMC_WAIT_INPUT or %PMC_WAIT_OUTPUT. + * %PMC_WAIT_INPUT for waiting input buffer data ready. + * %PMC_WAIT_OUTPUT for waiting output buffer empty. + * max_duration: The timeout value in usec. + */ +int eiois200_core_pmc_wait(int id, + enum eiois200_pmc_wait wait, + uint max_duration) +{ + u32 cnt =3D 0; + uint val; + int ret; + int new_timeout =3D max_duration ? max_duration : timeout; + ktime_t time_end =3D ktime_add_us(ktime_get(), new_timeout); + + if (new_timeout > TIMEOUT_MAX || + new_timeout < TIMEOUT_MIN) { + pr_err("Error timeout value: %dus\nTimeout value should between %d and %= d\n", + new_timeout, TIMEOUT_MIN, TIMEOUT_MAX); + return -ETIME; + } + + do { + ret =3D regmap_read(regmap_is200, + eiois200_dev->pmc[id].status, + &val); + if (ret) + return ret; + + if (wait =3D=3D PMC_WAIT_INPUT) { + if ((val & EIOIS200_PMC_STATUS_IBF) =3D=3D 0) + return 0; + } else { + if ((val & EIOIS200_PMC_STATUS_OBF) !=3D 0) + return 0; + } + + /* Incremental delay */ + fsleep(cnt++ * 10); + + } while (ktime_before(ktime_get(), time_end)); + + return -ETIME; +} +EXPORT_SYMBOL_GPL(eiois200_core_pmc_wait); + +/** + * eiois200_core_pmc_operation - Execute a pmc command + * @op: Pointer to an pmc command. + */ +int eiois200_core_pmc_operation(struct _pmc_op *op) +{ + u8 i; + int ret; + bool read_cmd =3D op->cmd & 0x01; + ktime_t t =3D ktime_get(); + + mutex_lock(&eiois200_dev->mutex); + + pmc_clear(op->chip); + + ret =3D pmc_write_cmd(op->chip, op->cmd, op->timeout); + if (ret) + goto err; + + ret =3D pmc_write_data(op->chip, op->control, op->timeout); + if (ret) + goto err; + + ret =3D pmc_write_data(op->chip, op->device_id, op->timeout); + if (ret) + goto err; + + ret =3D pmc_write_data(op->chip, op->size, op->timeout); + if (ret) + goto err; + + for (i =3D 0 ; i < op->size ; i++) { + if (read_cmd) + ret =3D pmc_read_data(op->chip, &op->payload[i], op->timeout); + else + ret =3D pmc_write_data(op->chip, op->payload[i], op->timeout); + + if (ret) + goto err; + } + + mutex_unlock(&eiois200_dev->mutex); + + return 0; + +err: + mutex_unlock(&eiois200_dev->mutex); + + pr_err("PMC error duration:%lldus\n", + ktime_to_us(ktime_sub(ktime_get(), t))); + pr_err(".cmd=3D0x%02X, .ctrl=3D0x%02X .id=3D0x%02X, .size=3D0x%02X .data= =3D0x%02X%02X\n", + op->cmd, op->control, op->device_id, + op->size, op->payload[0], op->payload[1]); + + return ret; +} +EXPORT_SYMBOL_GPL(eiois200_core_pmc_operation); + +static int get_pmc_port(struct device *dev, int id, struct eiois200_dev_po= rt *port) +{ + struct _pmc_port *pmc =3D &eiois200_dev->pmc[id]; + + is200_pnp_enter(port); + + /* Switch to PMC device page */ + is200_pnp_write(port, EIOIS200_LDN, EIOIS200_LDN_PMC1); + + /* Active this device */ + is200_pnp_write(port, EIOIS200_LDAR, EIOIS200_LDAR_LDACT); + + /* Get PMC cmd and data port */ + pmc->data =3D is200_pnp_read(port, EIOIS200_IOBA0H) << 8; + pmc->data |=3D is200_pnp_read(port, EIOIS200_IOBA0L); + pmc->cmd =3D is200_pnp_read(port, EIOIS200_IOBA1H) << 8; + pmc->cmd |=3D is200_pnp_read(port, EIOIS200_IOBA1L); + + /* Disable IRQ */ + is200_pnp_write(port, EIOIS200_IRQCTRL, 0); + + is200_pnp_leave(port); + + /* Make sure IO ports are not occupied */ + if (!devm_request_region(dev, pmc->data, 2, KBUILD_MODNAME)) { + dev_err(dev, "Request region %X error\n", pmc->data); + return -EBUSY; + } + + return 0; +} + +static int eiois200_exist(struct device *dev) +{ + u16 chip_id =3D 0; + u8 tmp =3D 0; + int i =3D 0; + int ret =3D -ENOMEM; + char chip[][8] =3D { "First", "Second" }; + + for (i =3D 0 ; i < ARRAY_SIZE(pnp_port) ; i++) { + struct eiois200_dev_port *port =3D pnp_port + i; + + if (!devm_request_region(dev, + pnp_port[i].idx, + 2, + KBUILD_MODNAME)) + continue; + + is200_pnp_enter(port); + + chip_id =3D is200_pnp_read(port, EIOIS200_CHIPID1) << 8; + chip_id |=3D is200_pnp_read(port, EIOIS200_CHIPID2); + + if (chip_id !=3D EIOIS200_CHIPID && + chip_id !=3D EIO201_211_CHIPID) + continue; + + /* Turn on the enable flag */ + tmp =3D is200_pnp_read(port, EIOIS200_SIOCTRL); + tmp |=3D EIOIS200_SIOCTRL_SIOEN; + is200_pnp_write(port, EIOIS200_SIOCTRL, tmp); + + is200_pnp_leave(port); + + ret =3D get_pmc_port(dev, i, port); + if (ret) + return ret; + + eiois200_dev->flag |=3D i =3D=3D 0 ? EIOIS200_F_CHIP_EXIST : + EIOIS200_F_SUB_CHIP_EXIST; + + pr_info("%s chip detected: %04X\n", chip[i], chip_id); + } + + return ret; +} + +/* read information about acpi stored in EC */ +static uint8_t acpiram_access(uint8_t offset) +{ + u8 val; + int ret; + + mutex_lock(&eiois200_dev->mutex); + + pmc_clear(0); + + ret =3D pmc_write_cmd(0, EIOIS200_PMC_CMD_ACPIRAM_READ, 0); + if (ret) + goto err; + + ret =3D pmc_write_data(0, offset, 0); + if (ret) + goto err; + + ret =3D pmc_write_data(0, 1, 0); + if (ret) + goto err; + + ret =3D pmc_read_data(0, &val, 0); + if (ret) + goto err; + +err: + mutex_unlock(&eiois200_dev->mutex); + return ret ? 0 : val; +} + +static int firmware_code_base(struct device *dev) +{ + u8 ic_vendor, ic_code, code_base; + + ic_vendor =3D acpiram_access(EIOIS200_ACPIRAM_ICVENDOR); + ic_code =3D acpiram_access(EIOIS200_ACPIRAM_ICCODE); + code_base =3D acpiram_access(EIOIS200_ACPIRAM_CODEBASE); + + if (ic_vendor !=3D 'R') + return -ENODEV; + + if (ic_code !=3D EIOIS200_ICCODE && + ic_code !=3D EIO201_ICCODE && + ic_code !=3D EIO211_ICCODE) + goto err; + + if (code_base =3D=3D 0x80) { + eiois200_dev->flag |=3D EIOIS200_F_NEW_CODE_BASE; + return 0; + } + + if (code_base =3D=3D 0 && (ic_code !=3D EIO201_ICCODE && + ic_code !=3D EIO211_ICCODE)) { + pr_info("Old code base not supported, yet."); + return -ENODEV; + } + + err: + dev_err(dev, + "Codebase check fail:\n" + "ic_vendor: 0x%X ,ic_code : 0x%X ,code_base : 0x%X\n", + ic_vendor, ic_code, code_base); + return -ENODEV; +} + +int eiois200_probe(struct device *dev, unsigned int id) +{ + int ret =3D 0; + void __iomem *iomem; + + iomem =3D devm_ioport_map(dev, 0, EIOIS200_SUB_PNP_DATA + 1); + if (!iomem) + return -ENOMEM; + + regmap_is200 =3D devm_regmap_init_mmio(dev, iomem, &pnp_regmap_config); + if (!regmap_is200) + return -ENOMEM; + + eiois200_dev =3D devm_kzalloc(dev, + sizeof(struct eiois200_dev), + GFP_KERNEL); + if (!eiois200_dev) + return -ENOMEM; + + mutex_init(&eiois200_dev->mutex); + + if (eiois200_exist(dev)) + return -ENODEV; + + if (firmware_code_base(dev)) { + dev_err(dev, "Chip code base check fail\n"); + return -EIO; + } + + dev_set_drvdata(dev, eiois200_dev); + + ret =3D devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, susi_mfd_devs, + ARRAY_SIZE(susi_mfd_devs), + NULL, 0, NULL); + if (ret) + dev_err(dev, "Cannot register child devices (error =3D %d)\n", ret); + + pr_info("%s started", KBUILD_MODNAME); + + return 0; +} + +struct { + char name[32]; + int cmd; + int ctrl; + int size; +} attrs[] =3D { + { "board_name", 0x53, 0x10, 16 }, + { "board_serial", 0x53, 0x1F, 16 }, + { "board_manufacturer", 0x53, 0x11, 16 }, + { "board_id", 0x53, 0x1E, 4 }, + { "firmware_version", 0x53, 0x22, 16 }, + { "firmware_build", 0x53, 0x23, 26 }, + { "firmware_date", 0x53, 0x24, 16 }, + { "chip_id", 0x53, 0x12, 12 }, + { "chip_detect", 0x53, 0x15, 12 }, + { "platform_type", 0x53, 0x13, 16 }, + { "platform_revision", 0x53, 0x14, 4 }, + { "eapi_version", 0x53, 0x30, 4 }, + { "eapi_id", 0x53, 0x31, 4 }, + { "boot_count", 0x55, 0x10, 4 }, + { "powerup_hour", 0x55, 0x11, 4 }, +}; + +static ssize_t info_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + uint i; + + for (i =3D 0 ; i < ARRAY_SIZE(attrs) ; i++) + if (!strcmp(attr->attr.name, attrs[i].name)) { + int ret; + char str[32] =3D ""; + struct _pmc_op op =3D { + .cmd =3D attrs[i].cmd, + .control =3D attrs[i].ctrl, + .payload =3D (u8 *)str, + .size =3D attrs[i].size, + }; + + ret =3D eiois200_core_pmc_operation(&op); + if (ret) + return ret; + + if (attrs[i].size =3D=3D 4) + return sysfs_emit(buf, "%X\n", *(u32 *)str); + else + return sysfs_emit(buf, "%s\n", str); + } + + return -EINVAL; +} + +static DEVICE_ATTR(board_name, 0444, info_show, NULL); +static DEVICE_ATTR(board_serial, 0444, info_show, NULL); +static DEVICE_ATTR(board_manufacturer, 0444, info_show, NULL); +static DEVICE_ATTR(firmware_version, 0444, info_show, NULL); +static DEVICE_ATTR(firmware_build, 0444, info_show, NULL); +static DEVICE_ATTR(firmware_date, 0444, info_show, NULL); +static DEVICE_ATTR(chip_id, 0444, info_show, NULL); +static DEVICE_ATTR(chip_detect, 0444, info_show, NULL); +static DEVICE_ATTR(platform_type, 0444, info_show, NULL); +static DEVICE_ATTR(platform_revision, 0444, info_show, NULL); +static DEVICE_ATTR(board_id, 0444, info_show, NULL); +static DEVICE_ATTR(eapi_version, 0444, info_show, NULL); +static DEVICE_ATTR(eapi_id, 0444, info_show, NULL); +static DEVICE_ATTR(boot_count, 0444, info_show, NULL); +static DEVICE_ATTR(powerup_hour, 0444, info_show, NULL); + +static struct attribute *pmc_attrs[] =3D { + &dev_attr_board_name.attr, + &dev_attr_board_serial.attr, + &dev_attr_board_manufacturer.attr, + &dev_attr_firmware_version.attr, + &dev_attr_firmware_build.attr, + &dev_attr_firmware_date.attr, + &dev_attr_chip_id.attr, + &dev_attr_chip_detect.attr, + &dev_attr_platform_type.attr, + &dev_attr_platform_revision.attr, + &dev_attr_board_id.attr, + &dev_attr_eapi_version.attr, + &dev_attr_eapi_id.attr, + &dev_attr_boot_count.attr, + &dev_attr_powerup_hour.attr, + NULL +}; + +static const struct attribute_group attr_group =3D { + .attrs =3D pmc_attrs, +}; + +static const struct attribute_group *attr_groups[] =3D { + &attr_group, + NULL +}; + +static struct isa_driver eiois200_driver =3D { + .probe =3D eiois200_probe, + + .driver =3D { + .owner =3D THIS_MODULE, + .name =3D KBUILD_MODNAME, + .dev_groups =3D attr_groups, + }, +}; + +module_isa_driver(eiois200_driver, 1); + +MODULE_AUTHOR("susi.driver "); +MODULE_DESCRIPTION("Advantech EIO-IS200 series EC core driver"); +MODULE_LICENSE("GPL v2"); --=20 2.34.1