Received: by 2002:ac0:8c9a:0:0:0:0:0 with SMTP id r26csp4795043ima; Tue, 5 Feb 2019 01:13:45 -0800 (PST) X-Google-Smtp-Source: AHgI3Ib538Pm4hPlMyQZc6Wy0F5n5k1PutAFcpJWnf40SZN7cC9+t8j0AjcoS+J5lJWS8E8PVy8x X-Received: by 2002:a62:f5da:: with SMTP id b87mr3959587pfm.253.1549358025594; Tue, 05 Feb 2019 01:13:45 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1549358025; cv=none; d=google.com; s=arc-20160816; b=yvNqlKNVctNMIpCr6g69n421iBbq4/GjVQ8Dp7gi80HGl9j4lz18tMp+2SKuM8vx8/ o7EQ9lRXCe2PK2uzXPBbKBt7seTu3SM8kKVrZ3Ucj0xP491X4GkyEZViL8oqrtB6wKwZ 1e+PYo2Gjns0BGJXQKKilv34UjzJsenj405/LibvKj/p9dvqQ35EHC14YM/wsLFzsQYv 9T/7j+YBql1WWztVvVtBQRfOhEmSaCAijubhMBv6zrOhk9rvOsQLG/wORiMohnwUHLjC AuFU7191ZU/X/Jy3ElLyMzeH6NPJeLBufbgP0GW1J3X3WFTFZYCm8B6/Uu0gJE1EFtr8 HQvw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=+maqpKXDDSLa/SivZKrHA1wzxn+Cac4rL9E6zQNZnP8=; b=BVHv3nUTyiSsZdYwedr6gaBzbC4yhzgUnaUR2LgIzhzWRWtRoW0Q7TGThRwgFi606/ gvzTuV8GHh50Qj+NkvQp2rjmrdcD8Dov48/D7/BmYnCVYLRI5T/q7kvPouW/PUe4RhiN dH5OVl36GYmLUd58oDFYt3WT2GifpBE1cg8QaEWT/TdPP2Rv0uTi2w/LvTf6xYYjjr66 pYci/O0F5nzZCLZyYZXd7X9WDY7C6khbxxRgUAOyfhVT+yKxs0YgZ6qclWHul3XtU6D8 uYcPv/a8YwQq+HCK1Eo4yy5NU7Z40Z/6/ROmWQsDc79UKtPEiK5m4BF+FF/9C+amNSly MUlg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@bgdev-pl.20150623.gappssmtp.com header.s=20150623 header.b=GYxOpwYk; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id e4si2649043pgk.127.2019.02.05.01.13.29; Tue, 05 Feb 2019 01:13:45 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@bgdev-pl.20150623.gappssmtp.com header.s=20150623 header.b=GYxOpwYk; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728857AbfBEJM7 (ORCPT + 99 others); Tue, 5 Feb 2019 04:12:59 -0500 Received: from mail-wr1-f68.google.com ([209.85.221.68]:46237 "EHLO mail-wr1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728776AbfBEJMz (ORCPT ); Tue, 5 Feb 2019 04:12:55 -0500 Received: by mail-wr1-f68.google.com with SMTP id l9so2677132wrt.13 for ; Tue, 05 Feb 2019 01:12:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bgdev-pl.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=+maqpKXDDSLa/SivZKrHA1wzxn+Cac4rL9E6zQNZnP8=; b=GYxOpwYk3guOyX9n5FqEt1/ypp8z9fuqy4XuhnHm8k2z5oPlCiG1EgSMlXP5LAtmdM xRP8BlwHfyqUR2cl5cSTgZxUM5VuUgUNEyva149cjWkclb90D18Farv2d0BwmP0kKgmW h2OZepEWiQOR66iYJmFRxFdUjrs761MfqCqNCnKR8tFSIbOiNb31UDzFMliICGsRULbz pb/M03luvWIzILv61QiLYzUpAQS2Qhp5XY9YLsEWAm4wrvRpoJ7hJZ/ro0e4//mpkPtv MKYbVOPw8F89rEEeoiahbMqRUqKQkm0PYPM80BY8/JSFnes91aBVfv75kGHpysMF9l4K xLIQ== 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=+maqpKXDDSLa/SivZKrHA1wzxn+Cac4rL9E6zQNZnP8=; b=RBM0OR7NTtPtdRC3HLsBVeYUW5Cq5Yi7obacSSbk9jOQt9AVoAySLduAn6lziqF4Y/ rxmjBkcdz4YoC9kusAcB22ph+JK2Z8nzNRBcJkWrmqhcz7IR+T9pwVadlVXGBkaPSnvu eXciH5VTixZzFAOBtH/d6dpnW8Ao8Tvxc9sotVLtzumzQn+LNsaiI4XKO8YUcyiyJHoQ JLrqWM1h4gvpbeoqIk3sJRDsw7UFOc8ndkj2+XTu9XtnW3ircwGkucmLQRdrI6kOB4TF 1/5YxG/ZlYPGEsWAjagTBi2vPd6NgAITAh/j9FIgPlpzVBsG750h8wxpv3AmUWQjKf9g 2B/A== X-Gm-Message-State: AHQUAuYwaS86QWTC5IzLfF9i/dsxvQqoxhf2aGZsC0S9a8v2vo65dJaA +vCCNQJbvqJNA4+Lnsouna5JVA== X-Received: by 2002:a5d:570c:: with SMTP id a12mr2682136wrv.161.1549357973850; Tue, 05 Feb 2019 01:12:53 -0800 (PST) Received: from debian-brgl.home ([2a01:cb1d:af:5b00:6d6c:8493:1ab5:dad7]) by smtp.gmail.com with ESMTPSA id s5sm10433657wmh.37.2019.02.05.01.12.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 05 Feb 2019 01:12:53 -0800 (PST) From: Bartosz Golaszewski To: Rob Herring , Mark Rutland , Linus Walleij , Dmitry Torokhov , Jacek Anaszewski , Pavel Machek , Lee Jones , Sebastian Reichel , Liam Girdwood , Greg Kroah-Hartman Cc: linux-kernel@vger.kernel.org, linux-gpio@vger.kernel.org, devicetree@vger.kernel.org, linux-input@vger.kernel.org, linux-leds@vger.kernel.org, linux-pm@vger.kernel.org, Bartosz Golaszewski Subject: [PATCH v4 07/10] gpio: max77650: add GPIO support Date: Tue, 5 Feb 2019 10:12:34 +0100 Message-Id: <20190205091237.6448-8-brgl@bgdev.pl> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190205091237.6448-1-brgl@bgdev.pl> References: <20190205091237.6448-1-brgl@bgdev.pl> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Bartosz Golaszewski Add GPIO support for max77650 mfd device. This PMIC exposes a single GPIO line. Signed-off-by: Bartosz Golaszewski --- drivers/gpio/Kconfig | 7 ++ drivers/gpio/Makefile | 1 + drivers/gpio/gpio-max77650.c | 190 +++++++++++++++++++++++++++++++++++ 3 files changed, 198 insertions(+) create mode 100644 drivers/gpio/gpio-max77650.c diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index b5a2845347ec..fb297fe5bfec 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -1095,6 +1095,13 @@ config GPIO_MAX77620 driver also provides interrupt support for each of the gpios. Say yes here to enable the max77620 to be used as gpio controller. +config GPIO_MAX77650 + tristate "Maxim MAX77650/77651 GPIO support" + depends on MFD_MAX77650 + help + GPIO driver for MAX77650/77651 PMIC from Maxim Semiconductor. + These chips have a single pin that can be configured as GPIO. + config GPIO_MSIC bool "Intel MSIC mixed signal gpio support" depends on (X86 || COMPILE_TEST) && MFD_INTEL_MSIC diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 37628f8dbf70..8bdad50db822 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -78,6 +78,7 @@ obj-$(CONFIG_GPIO_MAX7300) += gpio-max7300.o obj-$(CONFIG_GPIO_MAX7301) += gpio-max7301.o obj-$(CONFIG_GPIO_MAX732X) += gpio-max732x.o obj-$(CONFIG_GPIO_MAX77620) += gpio-max77620.o +obj-$(CONFIG_GPIO_MAX77650) += gpio-max77650.o obj-$(CONFIG_GPIO_MB86S7X) += gpio-mb86s7x.o obj-$(CONFIG_GPIO_MENZ127) += gpio-menz127.o obj-$(CONFIG_GPIO_MERRIFIELD) += gpio-merrifield.o diff --git a/drivers/gpio/gpio-max77650.c b/drivers/gpio/gpio-max77650.c new file mode 100644 index 000000000000..3f03f4e8956c --- /dev/null +++ b/drivers/gpio/gpio-max77650.c @@ -0,0 +1,190 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (C) 2018 BayLibre SAS +// Author: Bartosz Golaszewski +// +// GPIO driver for MAXIM 77650/77651 charger/power-supply. + +#include +#include +#include +#include +#include +#include + +#define MAX77650_GPIO_DIR_MASK BIT(0) +#define MAX77650_GPIO_INVAL_MASK BIT(1) +#define MAX77650_GPIO_DRV_MASK BIT(2) +#define MAX77650_GPIO_OUTVAL_MASK BIT(3) +#define MAX77650_GPIO_DEBOUNCE_MASK BIT(4) + +#define MAX77650_GPIO_DIR_OUT 0x00 +#define MAX77650_GPIO_DIR_IN BIT(0) +#define MAX77650_GPIO_OUT_LOW 0x00 +#define MAX77650_GPIO_OUT_HIGH BIT(3) +#define MAX77650_GPIO_DRV_OPEN_DRAIN 0x00 +#define MAX77650_GPIO_DRV_PUSH_PULL BIT(2) +#define MAX77650_GPIO_DEBOUNCE BIT(4) + +#define MAX77650_GPIO_DIR_BITS(_reg) \ + ((_reg) & MAX77650_GPIO_DIR_MASK) +#define MAX77650_GPIO_INVAL_BITS(_reg) \ + (((_reg) & MAX77650_GPIO_INVAL_MASK) >> 1) + +struct max77650_gpio_chip { + struct regmap *map; + struct gpio_chip gc; + int irq; +}; + +static int max77650_gpio_direction_input(struct gpio_chip *gc, + unsigned int offset) +{ + struct max77650_gpio_chip *chip = gpiochip_get_data(gc); + + return regmap_update_bits(chip->map, + MAX77650_REG_CNFG_GPIO, + MAX77650_GPIO_DIR_MASK, + MAX77650_GPIO_DIR_IN); +} + +static int max77650_gpio_direction_output(struct gpio_chip *gc, + unsigned int offset, int value) +{ + struct max77650_gpio_chip *chip = gpiochip_get_data(gc); + int mask, regval; + + mask = MAX77650_GPIO_DIR_MASK | MAX77650_GPIO_OUTVAL_MASK; + regval = value ? MAX77650_GPIO_OUT_HIGH : MAX77650_GPIO_OUT_LOW; + regval |= MAX77650_GPIO_DIR_OUT; + + return regmap_update_bits(chip->map, + MAX77650_REG_CNFG_GPIO, mask, regval); +} + +static void max77650_gpio_set_value(struct gpio_chip *gc, + unsigned int offset, int value) +{ + struct max77650_gpio_chip *chip = gpiochip_get_data(gc); + int rv, regval; + + regval = value ? MAX77650_GPIO_OUT_HIGH : MAX77650_GPIO_OUT_LOW; + + rv = regmap_update_bits(chip->map, MAX77650_REG_CNFG_GPIO, + MAX77650_GPIO_OUTVAL_MASK, regval); + if (rv) + dev_err(gc->parent, "cannot set GPIO value: %d\n", rv); +} + +static int max77650_gpio_get_value(struct gpio_chip *gc, + unsigned int offset) +{ + struct max77650_gpio_chip *chip = gpiochip_get_data(gc); + unsigned int val; + int rv; + + rv = regmap_read(chip->map, MAX77650_REG_CNFG_GPIO, &val); + if (rv) + return rv; + + return MAX77650_GPIO_INVAL_BITS(val); +} + +static int max77650_gpio_get_direction(struct gpio_chip *gc, + unsigned int offset) +{ + struct max77650_gpio_chip *chip = gpiochip_get_data(gc); + unsigned int val; + int rv; + + rv = regmap_read(chip->map, MAX77650_REG_CNFG_GPIO, &val); + if (rv) + return rv; + + return MAX77650_GPIO_DIR_BITS(val); +} + +static int max77650_gpio_set_config(struct gpio_chip *gc, + unsigned int offset, unsigned long cfg) +{ + struct max77650_gpio_chip *chip = gpiochip_get_data(gc); + + switch (pinconf_to_config_param(cfg)) { + case PIN_CONFIG_DRIVE_OPEN_DRAIN: + return regmap_update_bits(chip->map, + MAX77650_REG_CNFG_GPIO, + MAX77650_GPIO_DRV_MASK, + MAX77650_GPIO_DRV_OPEN_DRAIN); + case PIN_CONFIG_DRIVE_PUSH_PULL: + return regmap_update_bits(chip->map, + MAX77650_REG_CNFG_GPIO, + MAX77650_GPIO_DRV_MASK, + MAX77650_GPIO_DRV_PUSH_PULL); + case PIN_CONFIG_INPUT_DEBOUNCE: + return regmap_update_bits(chip->map, + MAX77650_REG_CNFG_GPIO, + MAX77650_GPIO_DEBOUNCE_MASK, + MAX77650_GPIO_DEBOUNCE); + default: + return -ENOTSUPP; + } +} + +static int max77650_gpio_to_irq(struct gpio_chip *gc, unsigned int offset) +{ + struct max77650_gpio_chip *chip = gpiochip_get_data(gc); + + return chip->irq; +} + +static int max77650_gpio_probe(struct platform_device *pdev) +{ + struct max77650_gpio_chip *chip; + struct device *dev, *parent; + struct i2c_client *i2c; + + dev = &pdev->dev; + parent = dev->parent; + i2c = to_i2c_client(parent); + + chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL); + if (!chip) + return -ENOMEM; + + chip->map = dev_get_regmap(parent, NULL); + if (!chip->map) + return -ENODEV; + + chip->irq = platform_get_irq_byname(pdev, "GPI"); + if (chip->irq < 0) + return chip->irq; + + chip->gc.base = -1; + chip->gc.ngpio = 1; + chip->gc.label = i2c->name; + chip->gc.parent = dev; + chip->gc.owner = THIS_MODULE; + chip->gc.can_sleep = true; + + chip->gc.direction_input = max77650_gpio_direction_input; + chip->gc.direction_output = max77650_gpio_direction_output; + chip->gc.set = max77650_gpio_set_value; + chip->gc.get = max77650_gpio_get_value; + chip->gc.get_direction = max77650_gpio_get_direction; + chip->gc.set_config = max77650_gpio_set_config; + chip->gc.to_irq = max77650_gpio_to_irq; + + return devm_gpiochip_add_data(dev, &chip->gc, chip); +} + +static struct platform_driver max77650_gpio_driver = { + .driver = { + .name = "max77650-gpio", + }, + .probe = max77650_gpio_probe, +}; +module_platform_driver(max77650_gpio_driver); + +MODULE_DESCRIPTION("MAXIM 77650/77651 GPIO driver"); +MODULE_AUTHOR("Bartosz Golaszewski "); +MODULE_LICENSE("GPL v2"); -- 2.20.1