Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp3347585yba; Tue, 23 Apr 2019 02:06:32 -0700 (PDT) X-Google-Smtp-Source: APXvYqwz/moLryOVRIbCVa1aL9WIQpeMk7JbTtzQF2SQfw42p6WCw7ubvHOCobN1ORVsimNLHTb7 X-Received: by 2002:a17:902:6b:: with SMTP id 98mr8997797pla.271.1556010392511; Tue, 23 Apr 2019 02:06:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1556010392; cv=none; d=google.com; s=arc-20160816; b=BejLiTuvwe/SFhiZX6FJStOtUcj0AqAQSatRI9JU6X/T3yAWlmr73wFQTr0B0g7ldi j+oENXROWPZi0ubU9cTyPx4YouvY3cULLYvs5WadkD0SKuXATu0+iV1cWiXil4HmC+6P VPPDlOWyLGYqLaWERZo7zR9jNL/2f74C7/nz4Ll1JDO7qUztRYCtheQEoiuJf+SVc+2r wWRMCoHcum7CGyPnaY+VKdyiJ6ppSct+aeVKYKHpHQ0ttNy4nS64TdLjJYF6uRGZfThw F3QvMSywg5K4eP8b5TlOI5suTXyZz6diCb01Gc+XCZuRq7//SQzDX8JpDPrvbIR0ZaHt MZ1A== 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=dD6qD8aDxGGtOlqjb5R5i7fbKB+IbD+zHB86wGROPnZG7BlW+CRF7mOWR15FxqgBdI KwVBRNHFbg0pJY8SH/tlf7euIEN0S4giezHFhTd1Pw5H+LuLl/St8aYsa5qDk7iTwHTc 1Wk1IKANf2Q2iiA1VFO2SubLhiqTWc+MnDX/L4auPZeezmkSeu/ckFptPDf4H4+thKZq hseja7+VKWM2JPwfLr0Bph4fWlwBCzI4vR73LONMi1mAsOqNdKRbffLbXyfvZnHLI6Jj rf5PNSEkiLzDcCcqtPSDIjHp/wxQCCHTzlN9zDvQ6EyLhMaaxU2saFGTnmtw1Mtqnm+2 d18w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@bgdev-pl.20150623.gappssmtp.com header.s=20150623 header.b=kqIrh3Qk; 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 z9si14976746plo.118.2019.04.23.02.06.17; Tue, 23 Apr 2019 02:06:32 -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=kqIrh3Qk; 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 S1727324AbfDWJFP (ORCPT + 99 others); Tue, 23 Apr 2019 05:05:15 -0400 Received: from mail-wr1-f68.google.com ([209.85.221.68]:45087 "EHLO mail-wr1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727282AbfDWJFM (ORCPT ); Tue, 23 Apr 2019 05:05:12 -0400 Received: by mail-wr1-f68.google.com with SMTP id s15so19106717wra.12 for ; Tue, 23 Apr 2019 02:05:11 -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=kqIrh3QkBua6pzb8F8WD7kn10cfCJFB92vaTwd5TblOE/U+V+TNR1Yy0J7/cYyKzZX 3Lqd13CiT8QOXRYDzaSDJJJId5KteEv7t/uu+L365LHq437lIHAoKj3nBWzNTfrJ6os1 j7GKfDbijFMuQxfCHQ9CnoZnp6Mz4hXWz8Ktq0V5YtTxmbZs9AsihrZC4GRQMeB9RE47 ipJ6/gZctnvqm9bPz3bjGl0qkLoaoKm1PNIbVuBaFkA1BHfuu8baV2k01OnTGzzQypZm Kh3dSBwDmW0gYVYK87BJYbuC/BZpe7vibdxuQduHA44uO/+kZY0THjNwsROe1b6zh2el 999w== 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=gEgA4NkEvhDu+W9xBQ/95ItYX1p9+INcla1lBtpwgSXAHHkpGWzsrSxSyAuu1bLmbn J6hLecoy9MqerEiv9F6VJOzuZrrjh2EDJDYm88HvbFvsegOUVaXQoione34mLUOWV9FG DnQHsvNv3O5klp6BQ02jlcJyR5NdYG281JNjjzQ/Qf3pI/P2OaVkGnV6xlGStARjgTMW rMrexLgr26bp0DrBmsWnDCWBmc7C7tkK4tsIhD2HdztW1f5N5FiOb31pq7TrhwkUlyFV U9P3wkFTXt0tef3eWnVAO1kk9GzuvmEMAc5O0b9+EK1bqERQkD2MfJ26AQMqNbQ5yQol 5KVw== X-Gm-Message-State: APjAAAU8R0ac/QgFjJXLlGyvZVhxTwmxo83G93nuX+wbDJIxraM64AJ3 WVSpzjY1dBaC/9GurRHvpgDnIw== X-Received: by 2002:a05:6000:2:: with SMTP id h2mr17324605wrx.76.1556010310550; Tue, 23 Apr 2019 02:05:10 -0700 (PDT) Received: from localhost.localdomain (aputeaux-684-1-25-101.w90-86.abo.wanadoo.fr. [90.86.250.101]) by smtp.gmail.com with ESMTPSA id v190sm15360434wme.18.2019.04.23.02.05.09 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 23 Apr 2019 02:05:09 -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 v10 08/11] gpio: max77650: add GPIO support Date: Tue, 23 Apr 2019 11:04:48 +0200 Message-Id: <20190423090451.23711-9-brgl@bgdev.pl> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190423090451.23711-1-brgl@bgdev.pl> References: <20190423090451.23711-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