Message ID | 20221116205822.1128275-3-Naresh.Solanki@9elements.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp61560wrr; Wed, 16 Nov 2022 13:06:32 -0800 (PST) X-Google-Smtp-Source: AA0mqf4lz8F+bte5ihbrIJFlTwuQQOcS4cmhH9lTh5m+9uYxvZaIM5IBVdOsqACkzGKzV7RhHyPL X-Received: by 2002:a17:90b:3a89:b0:205:ff5b:d27a with SMTP id om9-20020a17090b3a8900b00205ff5bd27amr5274562pjb.225.1668632792122; Wed, 16 Nov 2022 13:06:32 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1668632792; cv=none; d=google.com; s=arc-20160816; b=l2sn9aaCLI84wUD9o5BpX6g8a7WT6qW4s0oOgaUy4Ajynn6Yb4xLJhwl8e7tolmJYe aQLo8KWHtcDjIyMlJvimd3nFy9oRyu0qeJIeq3vrdt5e9+FRokZTa86MQtx01a1mgaJB xWLieWCPBl7EljHtmNmFQXrn2MX5YNvEVQBA+C8Jher9G5dNXHmPVD/7BQZRfWVjOvoC WCFCf4YV5LL2lKxzvlenkhsltS8XUZth6BlFnKvH7VDZvGaLDyF807POFj19rPnFcegN bMERkw7J/8a0BDoFOo1CFI2btty4h5mUjAqrBE6SXitCu8m7HTb7SfEWADWYXfGElXu7 7hdQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=omCTmMhelDFeQaccLb8U/KqxJQ8JVXEjyktZH4wBXdU=; b=RWYQPn9QvqbGlTH4FateG3SzTp/iZlRGmSIiOlArIbHLr5SA5X1CDsj0KFgkbGH3/w i/3d0x0DMfWzk1oIUBryqwBiwTPbGICKZRJSQJO8E77Q2vxqNIQaJ4TAHo/UUrTs81ZU UZDztdF6sauPB9FJiuIeztI+o6tymsNqg9YLs3e6z0ATBxdSRNslDzqD4bCIyiiC1lv9 8qNJYbFy1HIxGEyTZnBiF6IE5xpjLd3rgkB3h4DZRXKbV1CkCDGi9UqcKNafR+mk2MrH NYdB4xVctNmxgX1XPdTTB/EgvDizooI94jAGhWNSXLK1P8xfSV9XC/7dalom3kDQ/SHF qX7A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@9elements.com header.s=google header.b=NReEUX8y; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=9elements.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id e20-20020a63f554000000b0046fe97419aasi16522566pgk.120.2022.11.16.13.06.19; Wed, 16 Nov 2022 13:06:32 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@9elements.com header.s=google header.b=NReEUX8y; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=9elements.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233725AbiKPVBF (ORCPT <rfc822;just.gull.subs@gmail.com> + 99 others); Wed, 16 Nov 2022 16:01:05 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43992 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238755AbiKPVAg (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Wed, 16 Nov 2022 16:00:36 -0500 Received: from mail-wr1-x42c.google.com (mail-wr1-x42c.google.com [IPv6:2a00:1450:4864:20::42c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 082AE1C418 for <linux-kernel@vger.kernel.org>; Wed, 16 Nov 2022 12:58:32 -0800 (PST) Received: by mail-wr1-x42c.google.com with SMTP id cl5so32045869wrb.9 for <linux-kernel@vger.kernel.org>; Wed, 16 Nov 2022 12:58:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=9elements.com; s=google; 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=omCTmMhelDFeQaccLb8U/KqxJQ8JVXEjyktZH4wBXdU=; b=NReEUX8yUfpfq3IdQGU34XSaPzKJ71j8YsK3N4/PKn6zAveEAZRAlXAWE+bq7j94au S5IxNkWIPGhk/+DSkLV8RMJtc7LQCcLG4wmQGZwhyFDwcCe2SR0Wexcenv3JiN34FBYf XJTVnYrBdh8GnB4HUw6F89bn3h8BH2ANayawc4e3xTfrxlvjpNq++dH+NWBh1qM/1kfM hE0/PIjOPIn7KW9vDTE77W4tRh9uAGDcTUBZaOBYI83tt8LDWa7WF7qC3GIUEmMS7c7E qDVbKICGtA5Fa7Y1L2OHG08oIXDrABEuBfkGBfDvwmWncpqoPzIFhUlopEB/HdOTDIxs BgVw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=omCTmMhelDFeQaccLb8U/KqxJQ8JVXEjyktZH4wBXdU=; b=kC028tPBTtLqtTrOaJKLtVb7m4rkGxDBtUtpl7UL2mNLTGzfvFM0iBVRrkW4YPUz/j ni61YgPyrSEF+cOFpzO+4I9tjJuFi7poZtAo5gvwv6dbwflQcl+5mnIFDwaZTYrXOSgi qAgjJwaLXPCrmB6U69rUOgGKAUStxQ22NNp8d6aPO42C62QSQ6OzsmYkkEaBDzNoaMDq 9Lxc5vHE8yuuCgx66L9T2637Hi9O41KAt5LzP/qsUI1YNM7dMV58QarurnPNSEpDSCel 7JEBe9+kYHbcnDrtFIp8NQNlQfUAlLf0/Hu8eKJqD6cEJzGaQ9tKK+KTJrlP1VvH8iyR Rdig== X-Gm-Message-State: ANoB5pnZhruMVmGEXnKoSCqZSSO6H5klM6cMpD7j+HP/jBQ+bhdgt6J7 AEomCqIsz3Z4/2wAaqo+nV2syf8f78b5CDGR X-Received: by 2002:a5d:4050:0:b0:241:792f:a914 with SMTP id w16-20020a5d4050000000b00241792fa914mr12999251wrp.117.1668632310362; Wed, 16 Nov 2022 12:58:30 -0800 (PST) Received: from stroh80.sec.9e.network (ip-078-094-000-051.um19.pools.vodafone-ip.de. [78.94.0.51]) by smtp.gmail.com with ESMTPSA id u11-20020adfdd4b000000b002302dc43d77sm15886098wrm.115.2022.11.16.12.58.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 16 Nov 2022 12:58:30 -0800 (PST) From: Naresh Solanki <naresh.solanki@9elements.com> X-Google-Original-From: Naresh Solanki <Naresh.Solanki@9elements.com> To: linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Lee Jones <lee@kernel.org> Cc: Patrick Rudolph <patrick.rudolph@9elements.com>, Marcello Sylvester Bauer <sylv@sylv.io>, Naresh Solanki <Naresh.Solanki@9elements.com> Subject: [PATCH v11 2/2] mfd: max597x: Add support for MAX5970 and MAX5978 Date: Wed, 16 Nov 2022 21:58:22 +0100 Message-Id: <20221116205822.1128275-3-Naresh.Solanki@9elements.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20221116205822.1128275-1-Naresh.Solanki@9elements.com> References: <20221116205822.1128275-1-Naresh.Solanki@9elements.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1749688298876956171?= X-GMAIL-MSGID: =?utf-8?q?1749688298876956171?= |
Series |
mfd: max597x: Add support for max597x
|
|
Commit Message
Naresh Solanki
Nov. 16, 2022, 8:58 p.m. UTC
From: Patrick Rudolph <patrick.rudolph@9elements.com> Implement a regulator driver with IRQ support for fault management. Written against documentation [1] and [2] and tested on real hardware. Every channel has its own regulator supplies nammed 'vss1-supply' and 'vss2-supply'. The regulator supply is used to determine the output voltage, as the smart switch provides no output regulation. The driver requires the 'shunt-resistor-micro-ohms' property to be present in Device Tree to properly calculate current related values. Datasheet links: 1: https://datasheets.maximintegrated.com/en/ds/MAX5970.pdf 2: https://datasheets.maximintegrated.com/en/ds/MAX5978.pdf Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> Co-developed-by: Marcello Sylvester Bauer <sylv@sylv.io> Signed-off-by: Marcello Sylvester Bauer <sylv@sylv.io> Co-developed-by: Naresh Solanki <Naresh.Solanki@9elements.com> Signed-off-by: Naresh Solanki <Naresh.Solanki@9elements.com> --- drivers/mfd/Kconfig | 12 +++++ drivers/mfd/Makefile | 1 + drivers/mfd/max597x.c | 93 +++++++++++++++++++++++++++++++++ include/linux/mfd/max597x.h | 101 ++++++++++++++++++++++++++++++++++++ 4 files changed, 207 insertions(+) create mode 100644 drivers/mfd/max597x.c create mode 100644 include/linux/mfd/max597x.h
Comments
On Wed, 16 Nov 2022, Naresh Solanki wrote: > From: Patrick Rudolph <patrick.rudolph@9elements.com> > > Implement a regulator driver with IRQ support for fault management. > Written against documentation [1] and [2] and tested on real hardware. > > Every channel has its own regulator supplies nammed 'vss1-supply' and > 'vss2-supply'. The regulator supply is used to determine the output > voltage, as the smart switch provides no output regulation. > The driver requires the 'shunt-resistor-micro-ohms' property to be > present in Device Tree to properly calculate current related > values. > > Datasheet links: > 1: https://datasheets.maximintegrated.com/en/ds/MAX5970.pdf > 2: https://datasheets.maximintegrated.com/en/ds/MAX5978.pdf > > Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> > Co-developed-by: Marcello Sylvester Bauer <sylv@sylv.io> > Signed-off-by: Marcello Sylvester Bauer <sylv@sylv.io> > Co-developed-by: Naresh Solanki <Naresh.Solanki@9elements.com> > Signed-off-by: Naresh Solanki <Naresh.Solanki@9elements.com> > --- > drivers/mfd/Kconfig | 12 +++++ > drivers/mfd/Makefile | 1 + > drivers/mfd/max597x.c | 93 +++++++++++++++++++++++++++++++++ > include/linux/mfd/max597x.h | 101 ++++++++++++++++++++++++++++++++++++ > 4 files changed, 207 insertions(+) > create mode 100644 drivers/mfd/max597x.c > create mode 100644 include/linux/mfd/max597x.h Ignoring my comments won't make them go away. :) Please tell me why you need a whole new driver, instead of adding support to simple-mfd-i2c? > diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig > index 8b93856de432..416fe7986b7b 100644 > --- a/drivers/mfd/Kconfig > +++ b/drivers/mfd/Kconfig > @@ -253,6 +253,18 @@ config MFD_MADERA_SPI > Support for the Cirrus Logic Madera platform audio SoC > core functionality controlled via SPI. > > +config MFD_MAX597X > + tristate "Maxim 597x Power Switch and Monitor" > + depends on I2C > + depends on OF > + select MFD_CORE > + select REGMAP_I2C > + help > + This driver controls a Maxim 5970/5978 switch via I2C bus. > + The MAX5970/5978 is a smart switch with no output regulation, but > + fault protection and voltage and current monitoring capabilities. > + Also it supports upto 4 indication LEDs. > + > config MFD_CS47L15 > bool "Cirrus Logic CS47L15" > select PINCTRL_CS47L15 > diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile > index 7ed3ef4a698c..819d711fa748 100644 > --- a/drivers/mfd/Makefile > +++ b/drivers/mfd/Makefile > @@ -161,6 +161,7 @@ obj-$(CONFIG_MFD_DA9063) += da9063.o > obj-$(CONFIG_MFD_DA9150) += da9150-core.o > > obj-$(CONFIG_MFD_MAX14577) += max14577.o > +obj-$(CONFIG_MFD_MAX597X) += max597x.o > obj-$(CONFIG_MFD_MAX77620) += max77620.o > obj-$(CONFIG_MFD_MAX77650) += max77650.o > obj-$(CONFIG_MFD_MAX77686) += max77686.o > diff --git a/drivers/mfd/max597x.c b/drivers/mfd/max597x.c > new file mode 100644 > index 000000000000..45838413f24a > --- /dev/null > +++ b/drivers/mfd/max597x.c > @@ -0,0 +1,93 @@ > +// SPDX-License-Identifier: GPL-2.0 > +/* > + * Maxim MAX5970/MAX5978 Power Switch & Monitor > + * > + * Copyright (c) 2022 9elements GmbH > + * > + * Author: Patrick Rudolph <patrick.rudolph@9elements.com> > + */ > + > +#include <linux/i2c.h> > +#include <linux/mfd/core.h> > +#include <linux/mfd/max597x.h> > +#include <linux/regmap.h> > + > +static const struct regmap_config max597x_regmap_config = { > + .reg_bits = 8, > + .val_bits = 8, > + .max_register = MAX_REGISTERS, > +}; > + > +static const struct mfd_cell max597x_cells[] = { > + { .name = "max597x-regulator", }, > + { .name = "max597x-iio", }, > + { .name = "max597x-led", }, > +}; > + > +static int max597x_probe(struct i2c_client *i2c, const struct i2c_device_id *id) > +{ > + struct max597x_data *ddata; > + enum max597x_chip_type chip = id->driver_data; > + > + ddata = devm_kzalloc(&i2c->dev, sizeof(*ddata), GFP_KERNEL); > + if (!ddata) > + return -ENOMEM; > + > + /* > + * Based on chip type, Initialize the number of switch. This is needed by > + * regulator & iio cells. > + */ > + switch (chip) { > + case MAX597x_TYPE_MAX5970: > + ddata->num_switches = MAX5970_NUM_SWITCHES; > + break; > + case MAX597x_TYPE_MAX5978: > + ddata->num_switches = MAX5978_NUM_SWITCHES; > + break; > + } > + > + ddata->regmap = devm_regmap_init_i2c(i2c, &max597x_regmap_config); > + if (IS_ERR(ddata->regmap)) { > + dev_err(&i2c->dev, "Failed to initialize regmap"); > + return PTR_ERR(ddata->regmap); > + } > + > + /* IRQ used by regulator cell */ > + ddata->irq = i2c->irq; > + ddata->dev = &i2c->dev; > + i2c_set_clientdata(i2c, ddata); > + > + return devm_mfd_add_devices(ddata->dev, PLATFORM_DEVID_AUTO, > + max597x_cells, ARRAY_SIZE(max597x_cells), > + NULL, 0, NULL); > +} > + > +static const struct i2c_device_id max597x_table[] = { > + { .name = "max5970", MAX597x_TYPE_MAX5970 }, > + { .name = "max5978", MAX597x_TYPE_MAX5978 }, > + {} > +}; > + > +MODULE_DEVICE_TABLE(i2c, max597x_table); > + > +static const struct of_device_id max597x_of_match[] = { > + { .compatible = "maxim,max5970" }, > + { .compatible = "maxim,max5978" }, > + {} > +}; > + > +MODULE_DEVICE_TABLE(of, max597x_of_match); > + > +static struct i2c_driver max597x_driver = { > + .id_table = max597x_table, > + .driver = { > + .name = "max597x", > + .of_match_table = of_match_ptr(max597x_of_match), > + }, > + .probe = max597x_probe, > +}; > +module_i2c_driver(max597x_driver); > + > +MODULE_AUTHOR("Patrick Rudolph <patrick.rudolph@9elements.com>"); > +MODULE_DESCRIPTION("MAX597X Power Switch and Monitor"); > +MODULE_LICENSE("GPL v2"); > diff --git a/include/linux/mfd/max597x.h b/include/linux/mfd/max597x.h > new file mode 100644 > index 000000000000..706eff9c50a4 > --- /dev/null > +++ b/include/linux/mfd/max597x.h > @@ -0,0 +1,101 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > +/* > + * Maxim MAX5970/MAX5978 Power Switch & Monitor > + * > + * Copyright (c) 2022 9elements GmbH > + * > + * Author: Patrick Rudolph <patrick.rudolph@9elements.com> > + */ > + > +#ifndef MFD_MAX597X_H > +#define MFD_MAX597X_H > + > +#include <linux/device.h> > +#include <linux/regmap.h> > + > +#define MAX5970_NUM_SWITCHES 2 > +#define MAX5978_NUM_SWITCHES 1 > +#define MAX597X_NUM_LEDS 4 > + > +enum max597x_chip_type { > + MAX597x_TYPE_MAX5978 = 1, > + MAX597x_TYPE_MAX5970, > +}; > + > +#define MAX5970_REG_CURRENT_L(ch) (0x01 + (ch) * 4) > +#define MAX5970_REG_CURRENT_H(ch) (0x00 + (ch) * 4) > +#define MAX5970_REG_VOLTAGE_L(ch) (0x03 + (ch) * 4) > +#define MAX5970_REG_VOLTAGE_H(ch) (0x02 + (ch) * 4) > +#define MAX5970_REG_MON_RANGE 0x18 > +#define MAX5970_MON_MASK 0x3 > +#define MAX5970_MON(reg, ch) (((reg) >> ((ch) * 2)) & MAX5970_MON_MASK) > +#define MAX5970_MON_MAX_RANGE_UV 16000000 > + > +#define MAX5970_REG_CH_UV_WARN_H(ch) (0x1A + (ch) * 10) > +#define MAX5970_REG_CH_UV_WARN_L(ch) (0x1B + (ch) * 10) > +#define MAX5970_REG_CH_UV_CRIT_H(ch) (0x1C + (ch) * 10) > +#define MAX5970_REG_CH_UV_CRIT_L(ch) (0x1D + (ch) * 10) > +#define MAX5970_REG_CH_OV_WARN_H(ch) (0x1E + (ch) * 10) > +#define MAX5970_REG_CH_OV_WARN_L(ch) (0x1F + (ch) * 10) > +#define MAX5970_REG_CH_OV_CRIT_H(ch) (0x20 + (ch) * 10) > +#define MAX5970_REG_CH_OV_CRIT_L(ch) (0x21 + (ch) * 10) > + > +#define MAX5970_VAL2REG_H(x) (((x) >> 2) & 0xFF) > +#define MAX5970_VAL2REG_L(x) ((x) & 0x3) > + > +#define MAX5970_REG_DAC_FAST(ch) (0x2E + (ch)) > + > +#define MAX5970_FAST2SLOW_RATIO 200 > + > +#define MAX5970_REG_STATUS0 0x31 > +#define MAX5970_CB_IFAULTF(ch) (1 << (ch)) > +#define MAX5970_CB_IFAULTS(ch) (1 << ((ch) + 4)) > + > +#define MAX5970_REG_STATUS1 0x32 > +#define STATUS1_PROT_MASK 0x3 > +#define STATUS1_PROT(reg) \ > + (((reg) >> 6) & STATUS1_PROT_MASK) > +#define STATUS1_PROT_SHUTDOWN 0 > +#define STATUS1_PROT_CLEAR_PG 1 > +#define STATUS1_PROT_ALERT_ONLY 2 > + > +#define MAX5970_REG_STATUS2 0x33 > +#define MAX5970_IRNG_MASK 0x3 > +#define MAX5970_IRNG(reg, ch) \ > + (((reg) >> ((ch) * 2)) & MAX5970_IRNG_MASK) > + > +#define MAX5970_REG_STATUS3 0x34 > +#define MAX5970_STATUS3_ALERT BIT(4) > +#define MAX5970_STATUS3_PG(ch) BIT(ch) > + > +#define MAX5970_REG_FAULT0 0x35 > +#define UV_STATUS_WARN(ch) BIT(ch) > +#define UV_STATUS_CRIT(ch) BIT(ch + 4) > + > +#define MAX5970_REG_FAULT1 0x36 > +#define OV_STATUS_WARN(ch) BIT(ch) > +#define OV_STATUS_CRIT(ch) BIT(ch + 4) > + > +#define MAX5970_REG_FAULT2 0x37 > +#define OC_STATUS_WARN(ch) BIT(ch) > + > +#define MAX5970_REG_CHXEN 0x3b > +#define CHXEN(ch) (3 << (ch * 2)) > + > +#define MAX5970_REG_LED_FLASH 0x43 > + > +#define MAX_REGISTERS 0x49 > +#define ADC_MASK 0x3FF > + > +struct max597x_data { > + struct device *dev; > + int irq; > + int num_switches; > + struct regmap *regmap; > + /* Chip specific parameters needed by regulator & iio cells */ > + u32 irng[MAX5970_NUM_SWITCHES]; > + u32 mon_rng[MAX5970_NUM_SWITCHES]; > + u32 shunt_micro_ohms[MAX5970_NUM_SWITCHES]; > +}; > + > +#endif
On 17-11-2022 03:45 pm, Lee Jones wrote: > On Wed, 16 Nov 2022, Naresh Solanki wrote: > >> From: Patrick Rudolph <patrick.rudolph@9elements.com> >> >> Implement a regulator driver with IRQ support for fault management. >> Written against documentation [1] and [2] and tested on real hardware. >> >> Every channel has its own regulator supplies nammed 'vss1-supply' and >> 'vss2-supply'. The regulator supply is used to determine the output >> voltage, as the smart switch provides no output regulation. >> The driver requires the 'shunt-resistor-micro-ohms' property to be >> present in Device Tree to properly calculate current related >> values. >> >> Datasheet links: >> 1: https://datasheets.maximintegrated.com/en/ds/MAX5970.pdf >> 2: https://datasheets.maximintegrated.com/en/ds/MAX5978.pdf >> >> Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> >> Co-developed-by: Marcello Sylvester Bauer <sylv@sylv.io> >> Signed-off-by: Marcello Sylvester Bauer <sylv@sylv.io> >> Co-developed-by: Naresh Solanki <Naresh.Solanki@9elements.com> >> Signed-off-by: Naresh Solanki <Naresh.Solanki@9elements.com> >> --- >> drivers/mfd/Kconfig | 12 +++++ >> drivers/mfd/Makefile | 1 + >> drivers/mfd/max597x.c | 93 +++++++++++++++++++++++++++++++++ >> include/linux/mfd/max597x.h | 101 ++++++++++++++++++++++++++++++++++++ >> 4 files changed, 207 insertions(+) >> create mode 100644 drivers/mfd/max597x.c >> create mode 100644 include/linux/mfd/max597x.h > > Ignoring my comments won't make them go away. :) > > Please tell me why you need a whole new driver, instead of adding > support to simple-mfd-i2c? > I felt current implementation to be simpler, clearer & straight forward. >> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig >> index 8b93856de432..416fe7986b7b 100644 >> --- a/drivers/mfd/Kconfig >> +++ b/drivers/mfd/Kconfig >> @@ -253,6 +253,18 @@ config MFD_MADERA_SPI >> Support for the Cirrus Logic Madera platform audio SoC >> core functionality controlled via SPI. >> >> +config MFD_MAX597X >> + tristate "Maxim 597x Power Switch and Monitor" >> + depends on I2C >> + depends on OF >> + select MFD_CORE >> + select REGMAP_I2C >> + help >> + This driver controls a Maxim 5970/5978 switch via I2C bus. >> + The MAX5970/5978 is a smart switch with no output regulation, but >> + fault protection and voltage and current monitoring capabilities. >> + Also it supports upto 4 indication LEDs. >> + >> config MFD_CS47L15 >> bool "Cirrus Logic CS47L15" >> select PINCTRL_CS47L15 >> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile >> index 7ed3ef4a698c..819d711fa748 100644 >> --- a/drivers/mfd/Makefile >> +++ b/drivers/mfd/Makefile >> @@ -161,6 +161,7 @@ obj-$(CONFIG_MFD_DA9063) += da9063.o >> obj-$(CONFIG_MFD_DA9150) += da9150-core.o >> >> obj-$(CONFIG_MFD_MAX14577) += max14577.o >> +obj-$(CONFIG_MFD_MAX597X) += max597x.o >> obj-$(CONFIG_MFD_MAX77620) += max77620.o >> obj-$(CONFIG_MFD_MAX77650) += max77650.o >> obj-$(CONFIG_MFD_MAX77686) += max77686.o >> diff --git a/drivers/mfd/max597x.c b/drivers/mfd/max597x.c >> new file mode 100644 >> index 000000000000..45838413f24a >> --- /dev/null >> +++ b/drivers/mfd/max597x.c >> @@ -0,0 +1,93 @@ >> +// SPDX-License-Identifier: GPL-2.0 >> +/* >> + * Maxim MAX5970/MAX5978 Power Switch & Monitor >> + * >> + * Copyright (c) 2022 9elements GmbH >> + * >> + * Author: Patrick Rudolph <patrick.rudolph@9elements.com> >> + */ >> + >> +#include <linux/i2c.h> >> +#include <linux/mfd/core.h> >> +#include <linux/mfd/max597x.h> >> +#include <linux/regmap.h> >> + >> +static const struct regmap_config max597x_regmap_config = { >> + .reg_bits = 8, >> + .val_bits = 8, >> + .max_register = MAX_REGISTERS, >> +}; >> + >> +static const struct mfd_cell max597x_cells[] = { >> + { .name = "max597x-regulator", }, >> + { .name = "max597x-iio", }, >> + { .name = "max597x-led", }, >> +}; >> + >> +static int max597x_probe(struct i2c_client *i2c, const struct i2c_device_id *id) >> +{ >> + struct max597x_data *ddata; >> + enum max597x_chip_type chip = id->driver_data; >> + >> + ddata = devm_kzalloc(&i2c->dev, sizeof(*ddata), GFP_KERNEL); >> + if (!ddata) >> + return -ENOMEM; >> + >> + /* >> + * Based on chip type, Initialize the number of switch. This is needed by >> + * regulator & iio cells. >> + */ >> + switch (chip) { >> + case MAX597x_TYPE_MAX5970: >> + ddata->num_switches = MAX5970_NUM_SWITCHES; >> + break; >> + case MAX597x_TYPE_MAX5978: >> + ddata->num_switches = MAX5978_NUM_SWITCHES; >> + break; >> + } >> + >> + ddata->regmap = devm_regmap_init_i2c(i2c, &max597x_regmap_config); >> + if (IS_ERR(ddata->regmap)) { >> + dev_err(&i2c->dev, "Failed to initialize regmap"); >> + return PTR_ERR(ddata->regmap); >> + } >> + >> + /* IRQ used by regulator cell */ >> + ddata->irq = i2c->irq; >> + ddata->dev = &i2c->dev; >> + i2c_set_clientdata(i2c, ddata); >> + >> + return devm_mfd_add_devices(ddata->dev, PLATFORM_DEVID_AUTO, >> + max597x_cells, ARRAY_SIZE(max597x_cells), >> + NULL, 0, NULL); >> +} >> + >> +static const struct i2c_device_id max597x_table[] = { >> + { .name = "max5970", MAX597x_TYPE_MAX5970 }, >> + { .name = "max5978", MAX597x_TYPE_MAX5978 }, >> + {} >> +}; >> + >> +MODULE_DEVICE_TABLE(i2c, max597x_table); >> + >> +static const struct of_device_id max597x_of_match[] = { >> + { .compatible = "maxim,max5970" }, >> + { .compatible = "maxim,max5978" }, >> + {} >> +}; >> + >> +MODULE_DEVICE_TABLE(of, max597x_of_match); >> + >> +static struct i2c_driver max597x_driver = { >> + .id_table = max597x_table, >> + .driver = { >> + .name = "max597x", >> + .of_match_table = of_match_ptr(max597x_of_match), >> + }, >> + .probe = max597x_probe, >> +}; >> +module_i2c_driver(max597x_driver); >> + >> +MODULE_AUTHOR("Patrick Rudolph <patrick.rudolph@9elements.com>"); >> +MODULE_DESCRIPTION("MAX597X Power Switch and Monitor"); >> +MODULE_LICENSE("GPL v2"); >> diff --git a/include/linux/mfd/max597x.h b/include/linux/mfd/max597x.h >> new file mode 100644 >> index 000000000000..706eff9c50a4 >> --- /dev/null >> +++ b/include/linux/mfd/max597x.h >> @@ -0,0 +1,101 @@ >> +/* SPDX-License-Identifier: GPL-2.0 */ >> +/* >> + * Maxim MAX5970/MAX5978 Power Switch & Monitor >> + * >> + * Copyright (c) 2022 9elements GmbH >> + * >> + * Author: Patrick Rudolph <patrick.rudolph@9elements.com> >> + */ >> + >> +#ifndef MFD_MAX597X_H >> +#define MFD_MAX597X_H >> + >> +#include <linux/device.h> >> +#include <linux/regmap.h> >> + >> +#define MAX5970_NUM_SWITCHES 2 >> +#define MAX5978_NUM_SWITCHES 1 >> +#define MAX597X_NUM_LEDS 4 >> + >> +enum max597x_chip_type { >> + MAX597x_TYPE_MAX5978 = 1, >> + MAX597x_TYPE_MAX5970, >> +}; >> + >> +#define MAX5970_REG_CURRENT_L(ch) (0x01 + (ch) * 4) >> +#define MAX5970_REG_CURRENT_H(ch) (0x00 + (ch) * 4) >> +#define MAX5970_REG_VOLTAGE_L(ch) (0x03 + (ch) * 4) >> +#define MAX5970_REG_VOLTAGE_H(ch) (0x02 + (ch) * 4) >> +#define MAX5970_REG_MON_RANGE 0x18 >> +#define MAX5970_MON_MASK 0x3 >> +#define MAX5970_MON(reg, ch) (((reg) >> ((ch) * 2)) & MAX5970_MON_MASK) >> +#define MAX5970_MON_MAX_RANGE_UV 16000000 >> + >> +#define MAX5970_REG_CH_UV_WARN_H(ch) (0x1A + (ch) * 10) >> +#define MAX5970_REG_CH_UV_WARN_L(ch) (0x1B + (ch) * 10) >> +#define MAX5970_REG_CH_UV_CRIT_H(ch) (0x1C + (ch) * 10) >> +#define MAX5970_REG_CH_UV_CRIT_L(ch) (0x1D + (ch) * 10) >> +#define MAX5970_REG_CH_OV_WARN_H(ch) (0x1E + (ch) * 10) >> +#define MAX5970_REG_CH_OV_WARN_L(ch) (0x1F + (ch) * 10) >> +#define MAX5970_REG_CH_OV_CRIT_H(ch) (0x20 + (ch) * 10) >> +#define MAX5970_REG_CH_OV_CRIT_L(ch) (0x21 + (ch) * 10) >> + >> +#define MAX5970_VAL2REG_H(x) (((x) >> 2) & 0xFF) >> +#define MAX5970_VAL2REG_L(x) ((x) & 0x3) >> + >> +#define MAX5970_REG_DAC_FAST(ch) (0x2E + (ch)) >> + >> +#define MAX5970_FAST2SLOW_RATIO 200 >> + >> +#define MAX5970_REG_STATUS0 0x31 >> +#define MAX5970_CB_IFAULTF(ch) (1 << (ch)) >> +#define MAX5970_CB_IFAULTS(ch) (1 << ((ch) + 4)) >> + >> +#define MAX5970_REG_STATUS1 0x32 >> +#define STATUS1_PROT_MASK 0x3 >> +#define STATUS1_PROT(reg) \ >> + (((reg) >> 6) & STATUS1_PROT_MASK) >> +#define STATUS1_PROT_SHUTDOWN 0 >> +#define STATUS1_PROT_CLEAR_PG 1 >> +#define STATUS1_PROT_ALERT_ONLY 2 >> + >> +#define MAX5970_REG_STATUS2 0x33 >> +#define MAX5970_IRNG_MASK 0x3 >> +#define MAX5970_IRNG(reg, ch) \ >> + (((reg) >> ((ch) * 2)) & MAX5970_IRNG_MASK) >> + >> +#define MAX5970_REG_STATUS3 0x34 >> +#define MAX5970_STATUS3_ALERT BIT(4) >> +#define MAX5970_STATUS3_PG(ch) BIT(ch) >> + >> +#define MAX5970_REG_FAULT0 0x35 >> +#define UV_STATUS_WARN(ch) BIT(ch) >> +#define UV_STATUS_CRIT(ch) BIT(ch + 4) >> + >> +#define MAX5970_REG_FAULT1 0x36 >> +#define OV_STATUS_WARN(ch) BIT(ch) >> +#define OV_STATUS_CRIT(ch) BIT(ch + 4) >> + >> +#define MAX5970_REG_FAULT2 0x37 >> +#define OC_STATUS_WARN(ch) BIT(ch) >> + >> +#define MAX5970_REG_CHXEN 0x3b >> +#define CHXEN(ch) (3 << (ch * 2)) >> + >> +#define MAX5970_REG_LED_FLASH 0x43 >> + >> +#define MAX_REGISTERS 0x49 >> +#define ADC_MASK 0x3FF >> + >> +struct max597x_data { >> + struct device *dev; >> + int irq; >> + int num_switches; >> + struct regmap *regmap; >> + /* Chip specific parameters needed by regulator & iio cells */ >> + u32 irng[MAX5970_NUM_SWITCHES]; >> + u32 mon_rng[MAX5970_NUM_SWITCHES]; >> + u32 shunt_micro_ohms[MAX5970_NUM_SWITCHES]; >> +}; >> + >> +#endif >
On Fri, 18 Nov 2022, Naresh Solanki wrote: > > > On 17-11-2022 03:45 pm, Lee Jones wrote: > > On Wed, 16 Nov 2022, Naresh Solanki wrote: > > > > > From: Patrick Rudolph <patrick.rudolph@9elements.com> > > > > > > Implement a regulator driver with IRQ support for fault management. > > > Written against documentation [1] and [2] and tested on real hardware. > > > > > > Every channel has its own regulator supplies nammed 'vss1-supply' and > > > 'vss2-supply'. The regulator supply is used to determine the output > > > voltage, as the smart switch provides no output regulation. > > > The driver requires the 'shunt-resistor-micro-ohms' property to be > > > present in Device Tree to properly calculate current related > > > values. > > > > > > Datasheet links: > > > 1: https://datasheets.maximintegrated.com/en/ds/MAX5970.pdf > > > 2: https://datasheets.maximintegrated.com/en/ds/MAX5978.pdf > > > > > > Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> > > > Co-developed-by: Marcello Sylvester Bauer <sylv@sylv.io> > > > Signed-off-by: Marcello Sylvester Bauer <sylv@sylv.io> > > > Co-developed-by: Naresh Solanki <Naresh.Solanki@9elements.com> > > > Signed-off-by: Naresh Solanki <Naresh.Solanki@9elements.com> > > > --- > > > drivers/mfd/Kconfig | 12 +++++ > > > drivers/mfd/Makefile | 1 + > > > drivers/mfd/max597x.c | 93 +++++++++++++++++++++++++++++++++ > > > include/linux/mfd/max597x.h | 101 ++++++++++++++++++++++++++++++++++++ > > > 4 files changed, 207 insertions(+) > > > create mode 100644 drivers/mfd/max597x.c > > > create mode 100644 include/linux/mfd/max597x.h > > > > Ignoring my comments won't make them go away. :) > > > > Please tell me why you need a whole new driver, instead of adding > > support to simple-mfd-i2c? > > > I felt current implementation to be simpler, clearer & straight forward. If you can make it work with simple-mfd-i2c, please do so. No need to submit an entirely new driver for these simple use-cases.
Hi Lee On 08-12-2022 05:53 pm, Lee Jones wrote: > On Fri, 18 Nov 2022, Naresh Solanki wrote: > >> >> >> On 17-11-2022 03:45 pm, Lee Jones wrote: >>> On Wed, 16 Nov 2022, Naresh Solanki wrote: >>> >>>> From: Patrick Rudolph <patrick.rudolph@9elements.com> >>>> >>>> Implement a regulator driver with IRQ support for fault management. >>>> Written against documentation [1] and [2] and tested on real hardware. >>>> >>>> Every channel has its own regulator supplies nammed 'vss1-supply' and >>>> 'vss2-supply'. The regulator supply is used to determine the output >>>> voltage, as the smart switch provides no output regulation. >>>> The driver requires the 'shunt-resistor-micro-ohms' property to be >>>> present in Device Tree to properly calculate current related >>>> values. >>>> >>>> Datasheet links: >>>> 1: https://datasheets.maximintegrated.com/en/ds/MAX5970.pdf >>>> 2: https://datasheets.maximintegrated.com/en/ds/MAX5978.pdf >>>> >>>> Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> >>>> Co-developed-by: Marcello Sylvester Bauer <sylv@sylv.io> >>>> Signed-off-by: Marcello Sylvester Bauer <sylv@sylv.io> >>>> Co-developed-by: Naresh Solanki <Naresh.Solanki@9elements.com> >>>> Signed-off-by: Naresh Solanki <Naresh.Solanki@9elements.com> >>>> --- >>>> drivers/mfd/Kconfig | 12 +++++ >>>> drivers/mfd/Makefile | 1 + >>>> drivers/mfd/max597x.c | 93 +++++++++++++++++++++++++++++++++ >>>> include/linux/mfd/max597x.h | 101 ++++++++++++++++++++++++++++++++++++ >>>> 4 files changed, 207 insertions(+) >>>> create mode 100644 drivers/mfd/max597x.c >>>> create mode 100644 include/linux/mfd/max597x.h >>> >>> Ignoring my comments won't make them go away. :) >>> >>> Please tell me why you need a whole new driver, instead of adding >>> support to simple-mfd-i2c? >>> >> I felt current implementation to be simpler, clearer & straight forward. > > If you can make it work with simple-mfd-i2c, please do so. simple-mfd-i2c doesn't has mechanism to pass device type(max5978 vs max5970). > > No need to submit an entirely new driver for these simple use-cases. > Regards, Naresh
On Wed, 14 Dec 2022, Naresh Solanki wrote: > Hi Lee > > On 08-12-2022 05:53 pm, Lee Jones wrote: > > On Fri, 18 Nov 2022, Naresh Solanki wrote: > > > > > > > > > > > On 17-11-2022 03:45 pm, Lee Jones wrote: > > > > On Wed, 16 Nov 2022, Naresh Solanki wrote: > > > > > > > > > From: Patrick Rudolph <patrick.rudolph@9elements.com> > > > > > > > > > > Implement a regulator driver with IRQ support for fault management. > > > > > Written against documentation [1] and [2] and tested on real hardware. > > > > > > > > > > Every channel has its own regulator supplies nammed 'vss1-supply' and > > > > > 'vss2-supply'. The regulator supply is used to determine the output > > > > > voltage, as the smart switch provides no output regulation. > > > > > The driver requires the 'shunt-resistor-micro-ohms' property to be > > > > > present in Device Tree to properly calculate current related > > > > > values. > > > > > > > > > > Datasheet links: > > > > > 1: https://datasheets.maximintegrated.com/en/ds/MAX5970.pdf > > > > > 2: https://datasheets.maximintegrated.com/en/ds/MAX5978.pdf > > > > > > > > > > Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> > > > > > Co-developed-by: Marcello Sylvester Bauer <sylv@sylv.io> > > > > > Signed-off-by: Marcello Sylvester Bauer <sylv@sylv.io> > > > > > Co-developed-by: Naresh Solanki <Naresh.Solanki@9elements.com> > > > > > Signed-off-by: Naresh Solanki <Naresh.Solanki@9elements.com> > > > > > --- > > > > > drivers/mfd/Kconfig | 12 +++++ > > > > > drivers/mfd/Makefile | 1 + > > > > > drivers/mfd/max597x.c | 93 +++++++++++++++++++++++++++++++++ > > > > > include/linux/mfd/max597x.h | 101 ++++++++++++++++++++++++++++++++++++ > > > > > 4 files changed, 207 insertions(+) > > > > > create mode 100644 drivers/mfd/max597x.c > > > > > create mode 100644 include/linux/mfd/max597x.h > > > > > > > > Ignoring my comments won't make them go away. :) > > > > > > > > Please tell me why you need a whole new driver, instead of adding > > > > support to simple-mfd-i2c? > > > > > > > I felt current implementation to be simpler, clearer & straight forward. > > > > If you can make it work with simple-mfd-i2c, please do so. > simple-mfd-i2c doesn't has mechanism to pass device type(max5978 vs > max5970). `git grep silergy,sy7636a -- drivers/mfd` > > No need to submit an entirely new driver for these simple use-cases.
Hi Lee, On 14-12-2022 03:17 pm, Lee Jones wrote: > On Wed, 14 Dec 2022, Naresh Solanki wrote: > >> Hi Lee >> >> On 08-12-2022 05:53 pm, Lee Jones wrote: >>> On Fri, 18 Nov 2022, Naresh Solanki wrote: >>> >>>> >>>> >>>> On 17-11-2022 03:45 pm, Lee Jones wrote: >>>>> On Wed, 16 Nov 2022, Naresh Solanki wrote: >>>>> >>>>>> From: Patrick Rudolph <patrick.rudolph@9elements.com> >>>>>> >>>>>> Implement a regulator driver with IRQ support for fault management. >>>>>> Written against documentation [1] and [2] and tested on real hardware. >>>>>> >>>>>> Every channel has its own regulator supplies nammed 'vss1-supply' and >>>>>> 'vss2-supply'. The regulator supply is used to determine the output >>>>>> voltage, as the smart switch provides no output regulation. >>>>>> The driver requires the 'shunt-resistor-micro-ohms' property to be >>>>>> present in Device Tree to properly calculate current related >>>>>> values. >>>>>> >>>>>> Datasheet links: >>>>>> 1: https://datasheets.maximintegrated.com/en/ds/MAX5970.pdf >>>>>> 2: https://datasheets.maximintegrated.com/en/ds/MAX5978.pdf >>>>>> >>>>>> Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> >>>>>> Co-developed-by: Marcello Sylvester Bauer <sylv@sylv.io> >>>>>> Signed-off-by: Marcello Sylvester Bauer <sylv@sylv.io> >>>>>> Co-developed-by: Naresh Solanki <Naresh.Solanki@9elements.com> >>>>>> Signed-off-by: Naresh Solanki <Naresh.Solanki@9elements.com> >>>>>> --- >>>>>> drivers/mfd/Kconfig | 12 +++++ >>>>>> drivers/mfd/Makefile | 1 + >>>>>> drivers/mfd/max597x.c | 93 +++++++++++++++++++++++++++++++++ >>>>>> include/linux/mfd/max597x.h | 101 ++++++++++++++++++++++++++++++++++++ >>>>>> 4 files changed, 207 insertions(+) >>>>>> create mode 100644 drivers/mfd/max597x.c >>>>>> create mode 100644 include/linux/mfd/max597x.h >>>>> >>>>> Ignoring my comments won't make them go away. :) >>>>> >>>>> Please tell me why you need a whole new driver, instead of adding >>>>> support to simple-mfd-i2c? >>>>> >>>> I felt current implementation to be simpler, clearer & straight forward. >>> >>> If you can make it work with simple-mfd-i2c, please do so. >> simple-mfd-i2c doesn't has mechanism to pass device type(max5978 vs >> max5970). > > `git grep silergy,sy7636a -- drivers/mfd` I did check the driver but there is no mechanism to distinguish between chip variant i.e., 597x-regulator driver should be able to distinguish between max5978 vs max5970 chip type. > >>> No need to submit an entirely new driver for these simple use-cases. >
On Wed, 14 Dec 2022, Naresh Solanki wrote: > Hi Lee, > > On 14-12-2022 03:17 pm, Lee Jones wrote: > > On Wed, 14 Dec 2022, Naresh Solanki wrote: > > > > > Hi Lee > > > > > > On 08-12-2022 05:53 pm, Lee Jones wrote: > > > > On Fri, 18 Nov 2022, Naresh Solanki wrote: > > > > > > > > > > > > > > > > > > > On 17-11-2022 03:45 pm, Lee Jones wrote: > > > > > > On Wed, 16 Nov 2022, Naresh Solanki wrote: > > > > > > > > > > > > > From: Patrick Rudolph <patrick.rudolph@9elements.com> > > > > > > > > > > > > > > Implement a regulator driver with IRQ support for fault management. > > > > > > > Written against documentation [1] and [2] and tested on real hardware. > > > > > > > > > > > > > > Every channel has its own regulator supplies nammed 'vss1-supply' and > > > > > > > 'vss2-supply'. The regulator supply is used to determine the output > > > > > > > voltage, as the smart switch provides no output regulation. > > > > > > > The driver requires the 'shunt-resistor-micro-ohms' property to be > > > > > > > present in Device Tree to properly calculate current related > > > > > > > values. > > > > > > > > > > > > > > Datasheet links: > > > > > > > 1: https://datasheets.maximintegrated.com/en/ds/MAX5970.pdf > > > > > > > 2: https://datasheets.maximintegrated.com/en/ds/MAX5978.pdf > > > > > > > > > > > > > > Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> > > > > > > > Co-developed-by: Marcello Sylvester Bauer <sylv@sylv.io> > > > > > > > Signed-off-by: Marcello Sylvester Bauer <sylv@sylv.io> > > > > > > > Co-developed-by: Naresh Solanki <Naresh.Solanki@9elements.com> > > > > > > > Signed-off-by: Naresh Solanki <Naresh.Solanki@9elements.com> > > > > > > > --- > > > > > > > drivers/mfd/Kconfig | 12 +++++ > > > > > > > drivers/mfd/Makefile | 1 + > > > > > > > drivers/mfd/max597x.c | 93 +++++++++++++++++++++++++++++++++ > > > > > > > include/linux/mfd/max597x.h | 101 ++++++++++++++++++++++++++++++++++++ > > > > > > > 4 files changed, 207 insertions(+) > > > > > > > create mode 100644 drivers/mfd/max597x.c > > > > > > > create mode 100644 include/linux/mfd/max597x.h > > > > > > > > > > > > Ignoring my comments won't make them go away. :) > > > > > > > > > > > > Please tell me why you need a whole new driver, instead of adding > > > > > > support to simple-mfd-i2c? > > > > > > > > > > > I felt current implementation to be simpler, clearer & straight forward. > > > > > > > > If you can make it work with simple-mfd-i2c, please do so. > > > simple-mfd-i2c doesn't has mechanism to pass device type(max5978 vs > > > max5970). > > > > `git grep silergy,sy7636a -- drivers/mfd` > I did check the driver but there is no mechanism to distinguish between chip > variant i.e., 597x-regulator driver should be able to distinguish between > max5978 vs max5970 chip type. How is it doing that presently? Why can't the Regulator driver read the DT or match on the parent's compatible for itself? Providing a 100 line driver just to figure out a single value that is only going to be used in a single driver is a no-go. Please find a better way to solve this.
Hi Lee, On 23-12-2022 06:06 pm, Lee Jones wrote: > On Wed, 14 Dec 2022, Naresh Solanki wrote: > >> Hi Lee, >> >> On 14-12-2022 03:17 pm, Lee Jones wrote: >>> On Wed, 14 Dec 2022, Naresh Solanki wrote: >>> >>>> Hi Lee >>>> >>>> On 08-12-2022 05:53 pm, Lee Jones wrote: >>>>> On Fri, 18 Nov 2022, Naresh Solanki wrote: >>>>> >>>>>> >>>>>> >>>>>> On 17-11-2022 03:45 pm, Lee Jones wrote: >>>>>>> On Wed, 16 Nov 2022, Naresh Solanki wrote: >>>>>>> >>>>>>>> From: Patrick Rudolph <patrick.rudolph@9elements.com> >>>>>>>> >>>>>>>> Implement a regulator driver with IRQ support for fault management. >>>>>>>> Written against documentation [1] and [2] and tested on real hardware. >>>>>>>> >>>>>>>> Every channel has its own regulator supplies nammed 'vss1-supply' and >>>>>>>> 'vss2-supply'. The regulator supply is used to determine the output >>>>>>>> voltage, as the smart switch provides no output regulation. >>>>>>>> The driver requires the 'shunt-resistor-micro-ohms' property to be >>>>>>>> present in Device Tree to properly calculate current related >>>>>>>> values. >>>>>>>> >>>>>>>> Datasheet links: >>>>>>>> 1: https://datasheets.maximintegrated.com/en/ds/MAX5970.pdf >>>>>>>> 2: https://datasheets.maximintegrated.com/en/ds/MAX5978.pdf >>>>>>>> >>>>>>>> Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> >>>>>>>> Co-developed-by: Marcello Sylvester Bauer <sylv@sylv.io> >>>>>>>> Signed-off-by: Marcello Sylvester Bauer <sylv@sylv.io> >>>>>>>> Co-developed-by: Naresh Solanki <Naresh.Solanki@9elements.com> >>>>>>>> Signed-off-by: Naresh Solanki <Naresh.Solanki@9elements.com> >>>>>>>> --- >>>>>>>> drivers/mfd/Kconfig | 12 +++++ >>>>>>>> drivers/mfd/Makefile | 1 + >>>>>>>> drivers/mfd/max597x.c | 93 +++++++++++++++++++++++++++++++++ >>>>>>>> include/linux/mfd/max597x.h | 101 ++++++++++++++++++++++++++++++++++++ >>>>>>>> 4 files changed, 207 insertions(+) >>>>>>>> create mode 100644 drivers/mfd/max597x.c >>>>>>>> create mode 100644 include/linux/mfd/max597x.h >>>>>>> >>>>>>> Ignoring my comments won't make them go away. :) >>>>>>> >>>>>>> Please tell me why you need a whole new driver, instead of adding >>>>>>> support to simple-mfd-i2c? >>>>>>> >>>>>> I felt current implementation to be simpler, clearer & straight forward. >>>>> >>>>> If you can make it work with simple-mfd-i2c, please do so. >>>> simple-mfd-i2c doesn't has mechanism to pass device type(max5978 vs >>>> max5970). >>> >>> `git grep silergy,sy7636a -- drivers/mfd` >> I did check the driver but there is no mechanism to distinguish between chip >> variant i.e., 597x-regulator driver should be able to distinguish between >> max5978 vs max5970 chip type. > > How is it doing that presently? Using i2c_device_id. driver_data hold chip variant info based on compatible match. > > Why can't the Regulator driver read the DT or match on the parent's > compatible for itself? There are three drivers i.e., max597x regulator, led & iio driver. I'm not sure if checking compatible in each driver is ok. Recommendation ? > > Providing a 100 line driver just to figure out a single value that is > only going to be used in a single driver is a no-go. Please find a > better way to solve this.Yes but simple-mfd-i2c doesn't help in distinguishing chip variant & in situation like absence of device id register, mfd cell driver cant determine chip type to initialise accordingly. Can you please recommend me an approach that can also handle this kind of scenario. > Regards, Naresh
On Tue, 03 Jan 2023, Naresh Solanki wrote: > Hi Lee, > > On 23-12-2022 06:06 pm, Lee Jones wrote: > > On Wed, 14 Dec 2022, Naresh Solanki wrote: > > > > > Hi Lee, > > > > > > On 14-12-2022 03:17 pm, Lee Jones wrote: > > > > On Wed, 14 Dec 2022, Naresh Solanki wrote: > > > > > > > > > Hi Lee > > > > > > > > > > On 08-12-2022 05:53 pm, Lee Jones wrote: > > > > > > On Fri, 18 Nov 2022, Naresh Solanki wrote: > > > > > > > > > > > > > > > > > > > > > > > > > > > On 17-11-2022 03:45 pm, Lee Jones wrote: > > > > > > > > On Wed, 16 Nov 2022, Naresh Solanki wrote: > > > > > > > > > > > > > > > > > From: Patrick Rudolph <patrick.rudolph@9elements.com> > > > > > > > > > > > > > > > > > > Implement a regulator driver with IRQ support for fault management. > > > > > > > > > Written against documentation [1] and [2] and tested on real hardware. > > > > > > > > > > > > > > > > > > Every channel has its own regulator supplies nammed 'vss1-supply' and > > > > > > > > > 'vss2-supply'. The regulator supply is used to determine the output > > > > > > > > > voltage, as the smart switch provides no output regulation. > > > > > > > > > The driver requires the 'shunt-resistor-micro-ohms' property to be > > > > > > > > > present in Device Tree to properly calculate current related > > > > > > > > > values. > > > > > > > > > > > > > > > > > > Datasheet links: > > > > > > > > > 1: https://datasheets.maximintegrated.com/en/ds/MAX5970.pdf > > > > > > > > > 2: https://datasheets.maximintegrated.com/en/ds/MAX5978.pdf > > > > > > > > > > > > > > > > > > Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> > > > > > > > > > Co-developed-by: Marcello Sylvester Bauer <sylv@sylv.io> > > > > > > > > > Signed-off-by: Marcello Sylvester Bauer <sylv@sylv.io> > > > > > > > > > Co-developed-by: Naresh Solanki <Naresh.Solanki@9elements.com> > > > > > > > > > Signed-off-by: Naresh Solanki <Naresh.Solanki@9elements.com> > > > > > > > > > --- > > > > > > > > > drivers/mfd/Kconfig | 12 +++++ > > > > > > > > > drivers/mfd/Makefile | 1 + > > > > > > > > > drivers/mfd/max597x.c | 93 +++++++++++++++++++++++++++++++++ > > > > > > > > > include/linux/mfd/max597x.h | 101 ++++++++++++++++++++++++++++++++++++ > > > > > > > > > 4 files changed, 207 insertions(+) > > > > > > > > > create mode 100644 drivers/mfd/max597x.c > > > > > > > > > create mode 100644 include/linux/mfd/max597x.h > > > > > > > > > > > > > > > > Ignoring my comments won't make them go away. :) > > > > > > > > > > > > > > > > Please tell me why you need a whole new driver, instead of adding > > > > > > > > support to simple-mfd-i2c? > > > > > > > > > > > > > > > I felt current implementation to be simpler, clearer & straight forward. > > > > > > > > > > > > If you can make it work with simple-mfd-i2c, please do so. > > > > > simple-mfd-i2c doesn't has mechanism to pass device type(max5978 vs > > > > > max5970). > > > > > > > > `git grep silergy,sy7636a -- drivers/mfd` > > > I did check the driver but there is no mechanism to distinguish between chip > > > variant i.e., 597x-regulator driver should be able to distinguish between > > > max5978 vs max5970 chip type. > > > > How is it doing that presently? > Using i2c_device_id. driver_data hold chip variant info based on compatible > match. > > > > Why can't the Regulator driver read the DT or match on the parent's > > compatible for itself? > There are three drivers i.e., max597x regulator, led & iio driver. > I'm not sure if checking compatible in each driver is ok. > Recommendation ? Sure it is. The leaf devices can know that they are children and can read their parent's device tree node without issue. > > Providing a 100 line driver just to figure out a single value that is > > only going to be used in a single driver is a no-go. Please find a > > better way to solve this.Yes but simple-mfd-i2c doesn't help in > > distinguishing chip variant & in > situation like absence of device id register, mfd cell driver cant determine > chip type to initialise accordingly. > Can you please recommend me an approach that can also handle this kind of > scenario. Place the hardware IDs in DT.
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 8b93856de432..416fe7986b7b 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -253,6 +253,18 @@ config MFD_MADERA_SPI Support for the Cirrus Logic Madera platform audio SoC core functionality controlled via SPI. +config MFD_MAX597X + tristate "Maxim 597x Power Switch and Monitor" + depends on I2C + depends on OF + select MFD_CORE + select REGMAP_I2C + help + This driver controls a Maxim 5970/5978 switch via I2C bus. + The MAX5970/5978 is a smart switch with no output regulation, but + fault protection and voltage and current monitoring capabilities. + Also it supports upto 4 indication LEDs. + config MFD_CS47L15 bool "Cirrus Logic CS47L15" select PINCTRL_CS47L15 diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 7ed3ef4a698c..819d711fa748 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -161,6 +161,7 @@ obj-$(CONFIG_MFD_DA9063) += da9063.o obj-$(CONFIG_MFD_DA9150) += da9150-core.o obj-$(CONFIG_MFD_MAX14577) += max14577.o +obj-$(CONFIG_MFD_MAX597X) += max597x.o obj-$(CONFIG_MFD_MAX77620) += max77620.o obj-$(CONFIG_MFD_MAX77650) += max77650.o obj-$(CONFIG_MFD_MAX77686) += max77686.o diff --git a/drivers/mfd/max597x.c b/drivers/mfd/max597x.c new file mode 100644 index 000000000000..45838413f24a --- /dev/null +++ b/drivers/mfd/max597x.c @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Maxim MAX5970/MAX5978 Power Switch & Monitor + * + * Copyright (c) 2022 9elements GmbH + * + * Author: Patrick Rudolph <patrick.rudolph@9elements.com> + */ + +#include <linux/i2c.h> +#include <linux/mfd/core.h> +#include <linux/mfd/max597x.h> +#include <linux/regmap.h> + +static const struct regmap_config max597x_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = MAX_REGISTERS, +}; + +static const struct mfd_cell max597x_cells[] = { + { .name = "max597x-regulator", }, + { .name = "max597x-iio", }, + { .name = "max597x-led", }, +}; + +static int max597x_probe(struct i2c_client *i2c, const struct i2c_device_id *id) +{ + struct max597x_data *ddata; + enum max597x_chip_type chip = id->driver_data; + + ddata = devm_kzalloc(&i2c->dev, sizeof(*ddata), GFP_KERNEL); + if (!ddata) + return -ENOMEM; + + /* + * Based on chip type, Initialize the number of switch. This is needed by + * regulator & iio cells. + */ + switch (chip) { + case MAX597x_TYPE_MAX5970: + ddata->num_switches = MAX5970_NUM_SWITCHES; + break; + case MAX597x_TYPE_MAX5978: + ddata->num_switches = MAX5978_NUM_SWITCHES; + break; + } + + ddata->regmap = devm_regmap_init_i2c(i2c, &max597x_regmap_config); + if (IS_ERR(ddata->regmap)) { + dev_err(&i2c->dev, "Failed to initialize regmap"); + return PTR_ERR(ddata->regmap); + } + + /* IRQ used by regulator cell */ + ddata->irq = i2c->irq; + ddata->dev = &i2c->dev; + i2c_set_clientdata(i2c, ddata); + + return devm_mfd_add_devices(ddata->dev, PLATFORM_DEVID_AUTO, + max597x_cells, ARRAY_SIZE(max597x_cells), + NULL, 0, NULL); +} + +static const struct i2c_device_id max597x_table[] = { + { .name = "max5970", MAX597x_TYPE_MAX5970 }, + { .name = "max5978", MAX597x_TYPE_MAX5978 }, + {} +}; + +MODULE_DEVICE_TABLE(i2c, max597x_table); + +static const struct of_device_id max597x_of_match[] = { + { .compatible = "maxim,max5970" }, + { .compatible = "maxim,max5978" }, + {} +}; + +MODULE_DEVICE_TABLE(of, max597x_of_match); + +static struct i2c_driver max597x_driver = { + .id_table = max597x_table, + .driver = { + .name = "max597x", + .of_match_table = of_match_ptr(max597x_of_match), + }, + .probe = max597x_probe, +}; +module_i2c_driver(max597x_driver); + +MODULE_AUTHOR("Patrick Rudolph <patrick.rudolph@9elements.com>"); +MODULE_DESCRIPTION("MAX597X Power Switch and Monitor"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/mfd/max597x.h b/include/linux/mfd/max597x.h new file mode 100644 index 000000000000..706eff9c50a4 --- /dev/null +++ b/include/linux/mfd/max597x.h @@ -0,0 +1,101 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Maxim MAX5970/MAX5978 Power Switch & Monitor + * + * Copyright (c) 2022 9elements GmbH + * + * Author: Patrick Rudolph <patrick.rudolph@9elements.com> + */ + +#ifndef MFD_MAX597X_H +#define MFD_MAX597X_H + +#include <linux/device.h> +#include <linux/regmap.h> + +#define MAX5970_NUM_SWITCHES 2 +#define MAX5978_NUM_SWITCHES 1 +#define MAX597X_NUM_LEDS 4 + +enum max597x_chip_type { + MAX597x_TYPE_MAX5978 = 1, + MAX597x_TYPE_MAX5970, +}; + +#define MAX5970_REG_CURRENT_L(ch) (0x01 + (ch) * 4) +#define MAX5970_REG_CURRENT_H(ch) (0x00 + (ch) * 4) +#define MAX5970_REG_VOLTAGE_L(ch) (0x03 + (ch) * 4) +#define MAX5970_REG_VOLTAGE_H(ch) (0x02 + (ch) * 4) +#define MAX5970_REG_MON_RANGE 0x18 +#define MAX5970_MON_MASK 0x3 +#define MAX5970_MON(reg, ch) (((reg) >> ((ch) * 2)) & MAX5970_MON_MASK) +#define MAX5970_MON_MAX_RANGE_UV 16000000 + +#define MAX5970_REG_CH_UV_WARN_H(ch) (0x1A + (ch) * 10) +#define MAX5970_REG_CH_UV_WARN_L(ch) (0x1B + (ch) * 10) +#define MAX5970_REG_CH_UV_CRIT_H(ch) (0x1C + (ch) * 10) +#define MAX5970_REG_CH_UV_CRIT_L(ch) (0x1D + (ch) * 10) +#define MAX5970_REG_CH_OV_WARN_H(ch) (0x1E + (ch) * 10) +#define MAX5970_REG_CH_OV_WARN_L(ch) (0x1F + (ch) * 10) +#define MAX5970_REG_CH_OV_CRIT_H(ch) (0x20 + (ch) * 10) +#define MAX5970_REG_CH_OV_CRIT_L(ch) (0x21 + (ch) * 10) + +#define MAX5970_VAL2REG_H(x) (((x) >> 2) & 0xFF) +#define MAX5970_VAL2REG_L(x) ((x) & 0x3) + +#define MAX5970_REG_DAC_FAST(ch) (0x2E + (ch)) + +#define MAX5970_FAST2SLOW_RATIO 200 + +#define MAX5970_REG_STATUS0 0x31 +#define MAX5970_CB_IFAULTF(ch) (1 << (ch)) +#define MAX5970_CB_IFAULTS(ch) (1 << ((ch) + 4)) + +#define MAX5970_REG_STATUS1 0x32 +#define STATUS1_PROT_MASK 0x3 +#define STATUS1_PROT(reg) \ + (((reg) >> 6) & STATUS1_PROT_MASK) +#define STATUS1_PROT_SHUTDOWN 0 +#define STATUS1_PROT_CLEAR_PG 1 +#define STATUS1_PROT_ALERT_ONLY 2 + +#define MAX5970_REG_STATUS2 0x33 +#define MAX5970_IRNG_MASK 0x3 +#define MAX5970_IRNG(reg, ch) \ + (((reg) >> ((ch) * 2)) & MAX5970_IRNG_MASK) + +#define MAX5970_REG_STATUS3 0x34 +#define MAX5970_STATUS3_ALERT BIT(4) +#define MAX5970_STATUS3_PG(ch) BIT(ch) + +#define MAX5970_REG_FAULT0 0x35 +#define UV_STATUS_WARN(ch) BIT(ch) +#define UV_STATUS_CRIT(ch) BIT(ch + 4) + +#define MAX5970_REG_FAULT1 0x36 +#define OV_STATUS_WARN(ch) BIT(ch) +#define OV_STATUS_CRIT(ch) BIT(ch + 4) + +#define MAX5970_REG_FAULT2 0x37 +#define OC_STATUS_WARN(ch) BIT(ch) + +#define MAX5970_REG_CHXEN 0x3b +#define CHXEN(ch) (3 << (ch * 2)) + +#define MAX5970_REG_LED_FLASH 0x43 + +#define MAX_REGISTERS 0x49 +#define ADC_MASK 0x3FF + +struct max597x_data { + struct device *dev; + int irq; + int num_switches; + struct regmap *regmap; + /* Chip specific parameters needed by regulator & iio cells */ + u32 irng[MAX5970_NUM_SWITCHES]; + u32 mon_rng[MAX5970_NUM_SWITCHES]; + u32 shunt_micro_ohms[MAX5970_NUM_SWITCHES]; +}; + +#endif