Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp5777902yba; Thu, 11 Apr 2019 05:43:42 -0700 (PDT) X-Google-Smtp-Source: APXvYqzEPR6H93GL25PIbwifUjMhsjrufvEl882UbbMiI5x33wY5z5YtKJ9/dbHLgSNdXn5kVCfQ X-Received: by 2002:a17:902:d68d:: with SMTP id v13mr50477561ply.55.1554986622629; Thu, 11 Apr 2019 05:43:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1554986622; cv=none; d=google.com; s=arc-20160816; b=nKlMVtNVsYphUPR7Ll5tkOR1UDUGK2Gy9J1WZxgAtMnT3O4/OFTWA3j1+BC51Gu0tP XyIkf5X9GpU6S1cblBc2e5hxFa7b6zRzUyX5GQs7T8ZMYuQZAhYaJdQnKALorBgeqr37 oTlb8pSIMVYokcanK+Glr69TL5NkRw2y+8kJwZwYJmaCEPXJ/iAcv1Y4oWlexXamFqyL Z/RztnTEdpPiSoDW43pEKqOFHDEmFmgWZ9NpZ34V6UJXRhAVuJcEYgBBL9Az1bY7/8JA nzIXh+PhhIcpbCGD3YbOuhpsvKpa2xwyecy8D9XKXlZgdu4HyKQTZFAW4YMuh39hygqO 6StQ== 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=yGw5YilbSP88yNY2O1thS+S3CD6jvEmYujvzOlhreok=; b=fhGBKKOHhr4djYquZ5RJhaR/yq/FsU1767iSNf4N1BZtrixOPoJv7hE5J2hfYVuVmw iVvp8cyfCaXL79mI4OeafdR2wqtZ+VDQIhXZ8i8V847pijWPYT5OdNmW+d+rpGZyf2Rb PNTadw8dMEQ+TSg7E/uHwdR0CEHC7otunkk1rftS3uh7OhqTG6OO2xhF7yruBYXUxQjq lCWPwDARcE21/ah0t3Oeb1YO8LSIlU0BVQuVs1J8oOxn81Z05WMQfT3jalmnMunapy5/ i8uXUI/iIRdj6i/UcFdYL+FgnrebeQa3U/pivStvOLIgqen7UAI4l6nrXqElDg6zZ1/k AHCg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@bgdev-pl.20150623.gappssmtp.com header.s=20150623 header.b=F0ZzoDAJ; 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 g189si26395490pgc.112.2019.04.11.05.43.26; Thu, 11 Apr 2019 05:43:42 -0700 (PDT) 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=F0ZzoDAJ; 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 S1727001AbfDKMmi (ORCPT + 99 others); Thu, 11 Apr 2019 08:42:38 -0400 Received: from mail-wr1-f67.google.com ([209.85.221.67]:41792 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726912AbfDKMme (ORCPT ); Thu, 11 Apr 2019 08:42:34 -0400 Received: by mail-wr1-f67.google.com with SMTP id r4so7135830wrq.8 for ; Thu, 11 Apr 2019 05:42:32 -0700 (PDT) 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=yGw5YilbSP88yNY2O1thS+S3CD6jvEmYujvzOlhreok=; b=F0ZzoDAJggFNMzDfxp7ApFhTHbOn4ANm4ddTi5HmqIG8cswUWRnL870VpnIObkzxh0 v7J++KlFP+6aY2qoH87XGl9TX3Y+exmvDgJP63fjo/TFw15Pij/PD2ysdWXLhvi1Q2Kk DU8+po+Sq53qvKCx/QY4IhTg4VzAO4kTn4qj0gnCj5S6G1bH0dnqpAXmIX4cu2ATfeLT bg6sCXx6g3Dy6RQvjiBqFTECEydQF2eoN/SCRyj592IV1acO1t+Y76J1qRUHpcVdAdA2 Lhg2nv2jtYSM6E/UlaILpqW3k/sKgxEgGkbmAB/4XXQDo2y3swmPlU1aCb+Ryi6BkIx7 w/3A== 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=yGw5YilbSP88yNY2O1thS+S3CD6jvEmYujvzOlhreok=; b=COnMWWfU0kZp6yxGo6rMZyR5UM5Mqwerg5X0FyTj8bfbnMs7n23K2HUCxnIvbV7TFI h4vldjR2xk9C1bBOfJZ9ZKkf4hKnaYASBHMg0RHIhdD6vn9VGH9Zm61eqdoS9CnuCvep 6CPgcklB3Y9RlaeFV7J5PORkRUidI2+1twGZmAvCehDnAo7KYwmpP+TFfvfOFp8L5aRA Dub5jawM4/FZrwn7Y566yUagabto3VLkaJXaavESU8dZHAu+2wDTxj14NnmZqLIEYoiG 9sRWFLFCzWnFVg9EyeXqNj4STMPDGdhVxdydHyi8PTzGH0BZVsEw0gzLXyhu4pN8mY7w iCoQ== X-Gm-Message-State: APjAAAVQMRGpezH7irtmnzDxarF2edomrmgtxv/C8zEbesoOgvzlsuPE RkXzm9hkaO+moj02Df2+WMhwKw== X-Received: by 2002:adf:db0c:: with SMTP id s12mr31252499wri.184.1554986552117; Thu, 11 Apr 2019 05:42:32 -0700 (PDT) Received: from debian-brgl.home ([2a01:cb1d:af:5b00:6d6c:8493:1ab5:dad7]) by smtp.gmail.com with ESMTPSA id d4sm32894510wrv.42.2019.04.11.05.42.30 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 11 Apr 2019 05:42:31 -0700 (PDT) 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 v9 08/11] gpio: max77650: add GPIO support Date: Thu, 11 Apr 2019 14:42:09 +0200 Message-Id: <20190411124212.7612-9-brgl@bgdev.pl> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190411124212.7612-1-brgl@bgdev.pl> References: <20190411124212.7612-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 Reviewed-by: Linus Walleij --- 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 3f50526a771f..c4f912104440 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -1112,6 +1112,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 54d55274b93a..075722d8317d 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -80,6 +80,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.21.0