From patchwork Sun Aug 30 18:53:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 256891 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7C51CC433E6 for ; Sun, 30 Aug 2020 18:56:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 593412098B for ; Sun, 30 Aug 2020 18:56:08 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="eqfaNI4/" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726388AbgH3S4C (ORCPT ); Sun, 30 Aug 2020 14:56:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33268 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726412AbgH3SzF (ORCPT ); Sun, 30 Aug 2020 14:55:05 -0400 Received: from mail-lf1-x144.google.com (mail-lf1-x144.google.com [IPv6:2a00:1450:4864:20::144]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2674BC061575; Sun, 30 Aug 2020 11:55:05 -0700 (PDT) Received: by mail-lf1-x144.google.com with SMTP id c15so2325197lfi.3; Sun, 30 Aug 2020 11:55:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=gyFVRrq7oNAkyBDcab1pW5QCuvDZJBB4EknZ7t3FCyQ=; b=eqfaNI4/kuXYQV3upPkbU1Poja6coHGtkB3x+Zbdd5q/kvBXoQ3WVV9lVlV7SmiKJ2 u21imvSfFW/H0FNjchmlvEAXLj4xmsNmVgUbbZrvwGeNwR9G/mRS4eRzGYBM+cyW+gTg IZ17Q0jzzEWXu17fMMVPiuT5wqW0NWC57P0Pb8ZN+uf/HwK04jKAr42E5pQtSYOVOchw 3DbZh8uUm1VtQllkW3Oh6HsMoH+tB0dT2jLFkUdlyPf9BO8wKy9EN1j0BhBtphNMxdgg UYiUIxzauGngNYfKiHmjcosKfLOX1vKH1B5D91Ft2SIqdsTRkvsZwLx0nLnm/4RChzTF Y6HQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=gyFVRrq7oNAkyBDcab1pW5QCuvDZJBB4EknZ7t3FCyQ=; b=jvMu5R0E45gw2ptg3+6JANJyTs4ec0hUXNN7cbDT3sIRpAJqO04fFM1wKJkd2eYvjt nZfV1yRt1iPeLroCYAsiCp6o+bjz5bheuPsffytGejAsy3OpZQ0a0KML8B5iYlqTPTuZ DYKUZ4uQa5Lw+kbmSqXFQ0DhrMKpp8R625fFlr2vMneJWbJOUyYv3bhH2stMoOnegC3g S/y3lIcpBYFL1wbwQWoVsTcktQpZ/ccC1dCEyDjysSq7tHIKdnFbgPT2rWM5xDr3kZoO sVFqlJ29uEj9Y8ZGFZArvzINagdFXvBB0Rfqzrfj7VFz7+NykoONkHd7r2ZuFuTDGx7c iXKg== X-Gm-Message-State: AOAM532l4G5JV47ZAxThsu1HaAVoqBMyo9cH2yiG8k1ptXnXRIbwuaYh XG/3nMHD4o0nqBgS2s4B+Hc= X-Google-Smtp-Source: ABdhPJxSgb/zvqZMjCfnMXtPsXy8CIvbp061yJoZhxOfVfnVI7ZEnO98gX7KcwhZ8GNi9zDUFR/Yeg== X-Received: by 2002:ac2:51b4:: with SMTP id f20mr3884946lfk.188.1598813703445; Sun, 30 Aug 2020 11:55:03 -0700 (PDT) Received: from localhost.localdomain (109-252-170-211.dynamic.spd-mgts.ru. [109.252.170.211]) by smtp.gmail.com with ESMTPSA id n21sm21630ljc.89.2020.08.30.11.55.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 30 Aug 2020 11:55:02 -0700 (PDT) From: Dmitry Osipenko To: Lee Jones , Rob Herring , Thierry Reding , Jonathan Hunter , Pavel Machek , Dan Murphy , Sebastian Reichel , Lubomir Rintel , Mark Brown Cc: devicetree@vger.kernel.org, linux-tegra@vger.kernel.org, linux-leds@vger.kernel.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 1/6] dt-bindings: mfd: Add ENE KB930 Embedded Controller binding Date: Sun, 30 Aug 2020 21:53:51 +0300 Message-Id: <20200830185356.5365-2-digetx@gmail.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200830185356.5365-1-digetx@gmail.com> References: <20200830185356.5365-1-digetx@gmail.com> MIME-Version: 1.0 Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org Add binding document for the ENE KB930 Embedded Controller. Signed-off-by: Dmitry Osipenko --- .../devicetree/bindings/mfd/ene-kb930.yaml | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 Documentation/devicetree/bindings/mfd/ene-kb930.yaml diff --git a/Documentation/devicetree/bindings/mfd/ene-kb930.yaml b/Documentation/devicetree/bindings/mfd/ene-kb930.yaml new file mode 100644 index 000000000000..635c8966ca22 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/ene-kb930.yaml @@ -0,0 +1,66 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/ene-kb930.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ENE KB930 Embedded Controller bindings + +description: | + This binding describes the ENE KB930 Embedded Controller attached to an + I2C bus. + +maintainers: + - Dmitry Osipenko + +properties: + compatible: + items: + - enum: + - acer,a500-iconia-ec # Acer A500 Iconia tablet device + - enum: + - ene,kb930 + reg: + maxItems: 1 + + monitored-battery: true + power-supplies: true + system-power-controller: true + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + battery: battery-cell { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <3260000>; + energy-full-design-microwatt-hours = <24000000>; + operating-range-celsius = <0 40>; + }; + + mains: ac-adapter { + compatible = "gpio-charger"; + charger-type = "mains"; + gpios = <&gpio 125 0>; + }; + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + embedded-controller@58 { + compatible = "acer,a500-iconia-ec", "ene,kb930"; + reg = <0x58>; + + system-power-controller; + + monitored-battery = <&battery>; + power-supplies = <&mains>; + }; + }; + +... From patchwork Sun Aug 30 18:53:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 256893 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 003F2C433E7 for ; Sun, 30 Aug 2020 18:55:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D2DF3206CD for ; Sun, 30 Aug 2020 18:55:44 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="eSLpIkR4" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726506AbgH3SzN (ORCPT ); Sun, 30 Aug 2020 14:55:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33270 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726468AbgH3SzG (ORCPT ); Sun, 30 Aug 2020 14:55:06 -0400 Received: from mail-lj1-x241.google.com (mail-lj1-x241.google.com [IPv6:2a00:1450:4864:20::241]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EAA45C061573; Sun, 30 Aug 2020 11:55:05 -0700 (PDT) Received: by mail-lj1-x241.google.com with SMTP id v12so4236351ljc.10; Sun, 30 Aug 2020 11:55:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=bfkugI/LH5e/fdWRheFGhtoVkFSs2RbzC3QtJXx//30=; b=eSLpIkR4N6ywW9V7JdCundGyX+rsmoIUbuxQemwY84A+Nd67XcTfTg0OQkdoi9DaH3 PiX3MSSoS0lgV/zRFQlsRp3Y7OL1wGrZqPLgYYDNdRKW0VkE6PFTqUo3c4hW2goqotcQ Xanmi5x43qhTJLRPWjbf0+VnCbselVkfPxEKX7odWzjr46yFG4uI98s5L+1n3H+aRUzu 6PUBbK1Rp5u8N7xGRyifGK9eqK+Hwdx0otSUyYydn0Hp52HqOSoAfJ3rnnkGtgFoH0Ny Iw7B7fKkIkM0Z6KXX0F0Zz8Mm90Mch0Usi8h9d9vx4UajR3+Qqb9e6KquIkVQ4DwTnpA uGQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=bfkugI/LH5e/fdWRheFGhtoVkFSs2RbzC3QtJXx//30=; b=HMlpCvaSPGYEe+SUHrgLLJUysn1VlUoea6IPhlxMwqmd5bwDH16e604Mkpu25NT80h +IkFBEzGPpFwmRjZQPACJlx+g5fc4ZHU5kdJuFlkewt6jwcvLu6O8jGPFjFHQIWRFeVa rMQ6RumPdFLUOfYvbtj7uvF579/jFonydTiZsXjZDtoaybKA9cPc04Y25lfVUMjf8lMd pyNZAKoUezRMwPOLETExSzgQM4uG6sASYrUcicA45F/YpSMUrDsg4qjD10VVtMFtwE5k P3dnFPAN6g/13H+JX5jU0b6Z2Ra3MRFHM/B/7oKUqz9yaLC0Ekhj0ri7EllR30THug0F gU7Q== X-Gm-Message-State: AOAM532BujqQmHYiIVBwBa2Kw2N/2aLc5wnZUeWcHC4oUHq4IduyPLBK LF8MmE7lLZyrHwEOzNCMkU8= X-Google-Smtp-Source: ABdhPJyTua/0i+etpjIH7cfPsBa9xJiXpna9WtQiXng9CI46B2MDoc8yOJ7cUtJGuciz0gKzZCs5Dg== X-Received: by 2002:a2e:895a:: with SMTP id b26mr860324ljk.468.1598813704457; Sun, 30 Aug 2020 11:55:04 -0700 (PDT) Received: from localhost.localdomain (109-252-170-211.dynamic.spd-mgts.ru. [109.252.170.211]) by smtp.gmail.com with ESMTPSA id n21sm21630ljc.89.2020.08.30.11.55.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 30 Aug 2020 11:55:04 -0700 (PDT) From: Dmitry Osipenko To: Lee Jones , Rob Herring , Thierry Reding , Jonathan Hunter , Pavel Machek , Dan Murphy , Sebastian Reichel , Lubomir Rintel , Mark Brown Cc: devicetree@vger.kernel.org, linux-tegra@vger.kernel.org, linux-leds@vger.kernel.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 2/6] regmap: Use flexible sleep Date: Sun, 30 Aug 2020 21:53:52 +0300 Message-Id: <20200830185356.5365-3-digetx@gmail.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200830185356.5365-1-digetx@gmail.com> References: <20200830185356.5365-1-digetx@gmail.com> MIME-Version: 1.0 Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org The multi-reg write function uses udelay(), which is a busy-loop based delaying function that is not suitable for a long delays. Hence let's replace the udelay() with fsleep(), which is flexible sleep function that selects best delay function based on the delay-time. Signed-off-by: Dmitry Osipenko --- drivers/base/regmap/regmap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index e93700af7e6e..a417cb1a11dc 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -2231,7 +2231,7 @@ static int _regmap_range_multi_paged_reg_write(struct regmap *map, return ret; if (regs[i].delay_us) - udelay(regs[i].delay_us); + fsleep(regs[i].delay_us); base += n; n = 0; @@ -2268,7 +2268,7 @@ static int _regmap_multi_reg_write(struct regmap *map, return ret; if (regs[i].delay_us) - udelay(regs[i].delay_us); + fsleep(regs[i].delay_us); } return 0; } From patchwork Sun Aug 30 18:53:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Osipenko X-Patchwork-Id: 256892 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 164FDC2BBD0 for ; Sun, 30 Aug 2020 18:55:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E2A60208CA for ; Sun, 30 Aug 2020 18:55:50 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Zeggtg79" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726814AbgH3Szq (ORCPT ); Sun, 30 Aug 2020 14:55:46 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33280 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726488AbgH3SzJ (ORCPT ); Sun, 30 Aug 2020 14:55:09 -0400 Received: from mail-lj1-x244.google.com (mail-lj1-x244.google.com [IPv6:2a00:1450:4864:20::244]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 37AA6C061236; Sun, 30 Aug 2020 11:55:08 -0700 (PDT) Received: by mail-lj1-x244.google.com with SMTP id k25so1255465ljg.9; Sun, 30 Aug 2020 11:55:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=iKBN4c5URU3NkY5gudwPieJ8G8N2ImGEckJC0tR3bQ4=; b=Zeggtg79FI/kG9YvwJfDa1+8emzm7Sa47YneXv2LWpduISYJF5tElBJH9xsfg023Fn Pn7xWZ1fTtAdVJuLfRnK9jJr5wxM66n/W5bWl7Geds8KKDpoAAhNyc4Go9nIzxak7Ku6 rrhrgcuXskF3oMWWFq927qDVnWGXcspapiYCyqKeyPCPHGV7xcCM85EvqhitIqKFUihq dc26iNKzZ2UUBMuLH3E6sgRfA1VkYgtgwWUgPRXhvTa4zt8yhTTf0aiPAciLpRJO2rN3 QD53waqxNMVrOhsrD2H7Ypmj5+MSxTqrWP9VDR7DilEJyWJLcjxGqp2NY7Z3sAvVuDdF XQGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=iKBN4c5URU3NkY5gudwPieJ8G8N2ImGEckJC0tR3bQ4=; b=bHMn8VTXDbbP7QJZKpXHE2Bp0YVPyYvqT5yn91GY8hBsv7YzgElE5p9TVhLzc4IKqL AXn4SD7Y15oyVmpUwynzL2zTuMcu2VLHWbi4Qy97ysKkZuteTnNgr7GITTlLf5capcHL gYc7oKx/0WzmxAhKg3048n/oCl3Vc/EVA6aLho/Vp5Mjw9Fc/pcUhCeeQlfLY2SFP2yN /VfLFxILD6wGcjW5LZxMv1mYL1SAyIs3ri+uF4WCbwyS8FJADS92duIwC+W6W8e1JTj8 UVBfg6IsJq1Oc5W9WVZRNFr8Zijf+xu+Tl/Z4uxxd/otJRU/WKeGQ2vFdYscQ2CFVKOb TuxQ== X-Gm-Message-State: AOAM5319QLI5B9r7Gkae2iyLJ5zjBwtNnUqycO5CrkmrLSIg/7HkJuca UmNo70P5N4Lv3OPu4GYQRdA= X-Google-Smtp-Source: ABdhPJxbe0JBfxWKV/6NSjmi1mPXIXnK4XB7IBnEwsa3Dm0p/FOmm7LMFXKSanu0rdkfG55Ykh45kA== X-Received: by 2002:a2e:a28d:: with SMTP id k13mr3602274lja.11.1598813706596; Sun, 30 Aug 2020 11:55:06 -0700 (PDT) Received: from localhost.localdomain (109-252-170-211.dynamic.spd-mgts.ru. [109.252.170.211]) by smtp.gmail.com with ESMTPSA id n21sm21630ljc.89.2020.08.30.11.55.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 30 Aug 2020 11:55:06 -0700 (PDT) From: Dmitry Osipenko To: Lee Jones , Rob Herring , Thierry Reding , Jonathan Hunter , Pavel Machek , Dan Murphy , Sebastian Reichel , Lubomir Rintel , Mark Brown Cc: devicetree@vger.kernel.org, linux-tegra@vger.kernel.org, linux-leds@vger.kernel.org, linux-pm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 4/6] power: supply: Add battery gauge driver for Acer Iconia Tab A500 Date: Sun, 30 Aug 2020 21:53:54 +0300 Message-Id: <20200830185356.5365-5-digetx@gmail.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200830185356.5365-1-digetx@gmail.com> References: <20200830185356.5365-1-digetx@gmail.com> MIME-Version: 1.0 Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org This patch adds battery gauge driver for Acer Iconia Tab A500 device. The battery gauge function is provided via the Embedded Controller, which is found on the Acer A500. Signed-off-by: Dmitry Osipenko --- drivers/power/supply/Kconfig | 6 + drivers/power/supply/Makefile | 1 + drivers/power/supply/acer_a500_battery.c | 297 +++++++++++++++++++++++ 3 files changed, 304 insertions(+) create mode 100644 drivers/power/supply/acer_a500_battery.c diff --git a/drivers/power/supply/Kconfig b/drivers/power/supply/Kconfig index d1ccf17df42e..3daf0e359964 100644 --- a/drivers/power/supply/Kconfig +++ b/drivers/power/supply/Kconfig @@ -752,4 +752,10 @@ config CHARGER_WILCO information can be found in Documentation/ABI/testing/sysfs-class-power-wilco +config BATTERY_ACER_A500 + tristate "Acer Iconia Tab A500 battery driver" + depends on MFD_ACER_A500_EC + help + Say Y to include support for Acer Iconia Tab A500 battery fuel gauge. + endif # POWER_SUPPLY diff --git a/drivers/power/supply/Makefile b/drivers/power/supply/Makefile index b3c694a65114..08a5b49e2936 100644 --- a/drivers/power/supply/Makefile +++ b/drivers/power/supply/Makefile @@ -96,3 +96,4 @@ obj-$(CONFIG_CHARGER_UCS1002) += ucs1002_power.o obj-$(CONFIG_CHARGER_BD70528) += bd70528-charger.o obj-$(CONFIG_CHARGER_BD99954) += bd99954-charger.o obj-$(CONFIG_CHARGER_WILCO) += wilco-charger.o +obj-$(CONFIG_BATTERY_ACER_A500) += acer_a500_battery.o diff --git a/drivers/power/supply/acer_a500_battery.c b/drivers/power/supply/acer_a500_battery.c new file mode 100644 index 000000000000..93135933c8af --- /dev/null +++ b/drivers/power/supply/acer_a500_battery.c @@ -0,0 +1,297 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Battery driver for Acer Iconia Tab A500. + * + * Copyright 2020 GRATE-driver project. + * + * Based on downstream driver from Acer Inc. + * Based on NVIDIA Gas Gauge driver for SBS Compliant Batteries. + * + * Copyright (c) 2010, NVIDIA Corporation. + */ + +#include +#include +#include +#include +#include +#include +#include + +enum { + REG_CAPACITY, + REG_VOLTAGE, + REG_CURRENT, + REG_DESIGN_CAPACITY, + REG_TEMPERATURE, +}; + +#define EC_DATA(_reg, _psp) { \ + .psp = POWER_SUPPLY_PROP_ ## _psp, \ + .reg = _reg, \ +} + +static const struct battery_register { + enum power_supply_property psp; + unsigned int reg; +} ec_data[] = { + [REG_CAPACITY] = EC_DATA(0x00, CAPACITY), + [REG_VOLTAGE] = EC_DATA(0x01, VOLTAGE_NOW), + [REG_CURRENT] = EC_DATA(0x03, CURRENT_NOW), + [REG_DESIGN_CAPACITY] = EC_DATA(0x08, CHARGE_FULL_DESIGN), + [REG_TEMPERATURE] = EC_DATA(0x0a, TEMP), +}; + +static const enum power_supply_property a500_battery_properties[] = { + POWER_SUPPLY_PROP_CAPACITY, + POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN, + POWER_SUPPLY_PROP_CURRENT_NOW, + POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_STATUS, + POWER_SUPPLY_PROP_TECHNOLOGY, + POWER_SUPPLY_PROP_TEMP, + POWER_SUPPLY_PROP_VOLTAGE_NOW, +}; + +struct a500_battery { + struct delayed_work poll_work; + struct power_supply *psy; + struct regmap *rmap; + unsigned int capacity; +}; + +static bool a500_battery_update_capacity(struct a500_battery *bat) +{ + unsigned int capacity; + int err; + + err = regmap_read(bat->rmap, ec_data[REG_CAPACITY].reg, &capacity); + if (err) + return false; + + /* capacity can be >100% even if max value is 100% */ + capacity = min(capacity, 100u); + + if (bat->capacity != capacity) { + bat->capacity = capacity; + return true; + } + + return false; +} + +static int a500_battery_get_status(struct a500_battery *bat) +{ + if (bat->capacity < 100) { + if (power_supply_am_i_supplied(bat->psy)) + return POWER_SUPPLY_STATUS_CHARGING; + else + return POWER_SUPPLY_STATUS_DISCHARGING; + } + + return POWER_SUPPLY_STATUS_FULL; +} + +static void a500_battery_unit_adjustment(struct device *dev, + enum power_supply_property psp, + union power_supply_propval *val) +{ + const unsigned int base_unit_conversion = 1000; + const unsigned int temp_kelvin_to_celsius = 2731; + + switch (psp) { + case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: + case POWER_SUPPLY_PROP_CURRENT_NOW: + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + val->intval *= base_unit_conversion; + break; + + case POWER_SUPPLY_PROP_TEMP: + val->intval -= temp_kelvin_to_celsius; + break; + + case POWER_SUPPLY_PROP_PRESENT: + val->intval = !!val->intval; + break; + + default: + dev_dbg(dev, + "%s: no need for unit conversion %d\n", __func__, psp); + } +} + +static int a500_battery_get_ec_data_index(struct device *dev, + enum power_supply_property psp) +{ + unsigned int i; + + /* + * DESIGN_CAPACITY register always returns a non-zero value if + * battery is connected and zero if disconnected, hence we'll use + * it for judging the battery presence. + */ + if (psp == POWER_SUPPLY_PROP_PRESENT) + psp = POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN; + + for (i = 0; i < ARRAY_SIZE(ec_data); i++) + if (psp == ec_data[i].psp) + return i; + + dev_dbg(dev, "%s: invalid property %u\n", __func__, psp); + + return -EINVAL; +} + +static int a500_battery_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct a500_battery *bat = power_supply_get_drvdata(psy); + struct device *dev = psy->dev.parent; + int ret = 0; + + switch (psp) { + case POWER_SUPPLY_PROP_STATUS: + val->intval = a500_battery_get_status(bat); + break; + + case POWER_SUPPLY_PROP_TECHNOLOGY: + val->intval = POWER_SUPPLY_TECHNOLOGY_LION; + break; + + case POWER_SUPPLY_PROP_CAPACITY: + a500_battery_update_capacity(bat); + val->intval = bat->capacity; + break; + + case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN: + case POWER_SUPPLY_PROP_CURRENT_NOW: + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + case POWER_SUPPLY_PROP_PRESENT: + case POWER_SUPPLY_PROP_TEMP: + ret = a500_battery_get_ec_data_index(dev, psp); + if (ret < 0) + break; + + ret = regmap_read(bat->rmap, ec_data[ret].reg, &val->intval); + break; + + default: + dev_err(dev, "%s: invalid property %u\n", __func__, psp); + return -EINVAL; + } + + if (!ret) { + /* convert units to match requirements of power supply class */ + a500_battery_unit_adjustment(dev, psp, val); + } + + dev_dbg(dev, "%s: property = %d, value = %x\n", + __func__, psp, val->intval); + + /* return NODATA for properties if battery not presents */ + if (ret) + return -ENODATA; + + return 0; +} + +static void a500_battery_poll_work(struct work_struct *work) +{ + struct a500_battery *bat; + bool capacity_changed; + + bat = container_of(work, struct a500_battery, poll_work.work); + capacity_changed = a500_battery_update_capacity(bat); + + if (capacity_changed) + power_supply_changed(bat->psy); + + /* continuously send uevent notification */ + schedule_delayed_work(&bat->poll_work, 30 * HZ); +} + +static const struct power_supply_desc a500_battery_desc = { + .name = "ec-battery", + .type = POWER_SUPPLY_TYPE_BATTERY, + .properties = a500_battery_properties, + .get_property = a500_battery_get_property, + .num_properties = ARRAY_SIZE(a500_battery_properties), + .external_power_changed = power_supply_changed, +}; + +static int a500_battery_probe(struct platform_device *pdev) +{ + struct power_supply_config psy_cfg = {}; + struct a500_battery *bat; + + bat = devm_kzalloc(&pdev->dev, sizeof(*bat), GFP_KERNEL); + if (!bat) + return -ENOMEM; + + platform_set_drvdata(pdev, bat); + + psy_cfg.of_node = pdev->dev.parent->of_node; + psy_cfg.drv_data = bat; + + bat->rmap = dev_get_regmap(pdev->dev.parent, "KB930"); + if (!bat->rmap) + return -EINVAL; + + bat->psy = devm_power_supply_register_no_ws(&pdev->dev, + &a500_battery_desc, + &psy_cfg); + if (IS_ERR(bat->psy)) + return dev_err_probe(&pdev->dev, PTR_ERR(bat->psy), + "failed to register battery\n"); + + INIT_DELAYED_WORK(&bat->poll_work, a500_battery_poll_work); + schedule_delayed_work(&bat->poll_work, HZ); + + return 0; +} + +static int a500_battery_remove(struct platform_device *pdev) +{ + struct a500_battery *bat = dev_get_drvdata(&pdev->dev); + + cancel_delayed_work_sync(&bat->poll_work); + + return 0; +} + +static int __maybe_unused a500_battery_suspend(struct device *dev) +{ + struct a500_battery *bat = dev_get_drvdata(dev); + + cancel_delayed_work_sync(&bat->poll_work); + + return 0; +} + +static int __maybe_unused a500_battery_resume(struct device *dev) +{ + struct a500_battery *bat = dev_get_drvdata(dev); + + schedule_delayed_work(&bat->poll_work, HZ); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(a500_battery_pm_ops, + a500_battery_suspend, a500_battery_resume); + +static struct platform_driver a500_battery_driver = { + .driver = { + .name = "acer-a500-iconia-battery", + .pm = &a500_battery_pm_ops, + }, + .probe = a500_battery_probe, + .remove = a500_battery_remove, +}; +module_platform_driver(a500_battery_driver); + +MODULE_DESCRIPTION("Battery gauge driver for Acer Iconia Tab A500"); +MODULE_AUTHOR("Dmitry Osipenko "); +MODULE_ALIAS("platform:acer-a500-iconia-battery"); +MODULE_LICENSE("GPL");