Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp4467921ybi; Tue, 11 Jun 2019 07:09:56 -0700 (PDT) X-Google-Smtp-Source: APXvYqxoQSqZSWa2nVGhyokhxscY/tJJNajmEN/vLLqEdl7O5yVSITUK3RosfSddektKMWO/XrVk X-Received: by 2002:a63:5158:: with SMTP id r24mr20387239pgl.79.1560262196539; Tue, 11 Jun 2019 07:09:56 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1560262196; cv=none; d=google.com; s=arc-20160816; b=h6fvCKptr4OlFUPfhT5Gl5k/N22iMuRj/JWaxZQtDKnxN/FKJ1OEVz6/rOyqhd7Mi3 TprUtimLRbHnsSa6wL4HxUXgL3YjmFz4RdFVHqDDDEm7YpPx7hTGwzQkZjzhGGjjOzQL 2YyuVJMJRuQB0Uc6SuP+oo2aejAHH9h+pvirB20n/gXDF7KlbnWNIye+Nf3nhH8hfKXo v3khiIhHf1DsDdw327s8vPDsURz0nA4ddH0CCjeD7qX1ktBzR5uQitHkhks1AeybgYGd ViyAPtkSW11tULZaznkpaMXfZhgoE7dd30+1vWh9rtXqqVJSY8avgx0fgHI98RfFzwbG 9lwA== 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; bh=cPy1qYCu8bcQICfzk2GYEtLhIkBiY7SsbAJ9su+f31Q=; b=GhoaPqtrafoQCKyZECN+/m2PEePjueod3GLg7TZv0OFfnq9zugMJxdIqTri04WAbxX hNRB0S86wgeVg01NfczhwFaeOnyOIzmW4GY9FcWYWqBQiy0ZP+NGgc3mwNc/WybrC0Wb 1GDUV5/0RtuURuCcAUq04lEL3HLwpkY2sT9TKazRE7oZEXQtTnGSohCjRvyyWGsga3f2 s08Tl9xUZuwmZHzEhE3c8KVlAITgIpMN4CjdmC04ualwT9yuqwqKenr1K8hMxnrc2LWe YGTK2RIDBZ2QaNITVnWomujPjO62NsyKJzpps75csadtcORgjx2RVL6rAMjwyJxJhpXf KyyQ== ARC-Authentication-Results: i=1; mx.google.com; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=codethink.co.uk Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id c14si8385676pgi.96.2019.06.11.07.09.40; Tue, 11 Jun 2019 07:09:56 -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; 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; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=codethink.co.uk Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390639AbfFKOFV (ORCPT + 99 others); Tue, 11 Jun 2019 10:05:21 -0400 Received: from imap1.codethink.co.uk ([176.9.8.82]:55776 "EHLO imap1.codethink.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390065AbfFKOFE (ORCPT ); Tue, 11 Jun 2019 10:05:04 -0400 Received: from [167.98.27.226] (helo=happy.office.codethink.co.uk) by imap1.codethink.co.uk with esmtpsa (Exim 4.84_2 #1 (Debian)) id 1hahOW-0003vU-6D; Tue, 11 Jun 2019 15:05:00 +0100 From: Michael Drake To: Andrzej Hajda , Laurent Pinchart , dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Michael Drake Cc: David Airlie , Daniel Vetter , Rob Herring , Mark Rutland , linux-kernel@lists.codethink.co.uk, Patrick Glaser , Nate Case Subject: [PATCH v1 11/11] ti949: Add support for configuration via device properties Date: Tue, 11 Jun 2019 15:04:12 +0100 Message-Id: <20190611140412.32151-12-michael.drake@codethink.co.uk> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190611140412.32151-1-michael.drake@codethink.co.uk> References: <20190611140412.32151-1-michael.drake@codethink.co.uk> 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 This allows the device to be configured for the board in device tree, or in ACPI tables. The device node properties can provide an array of register addresses and values to be written to configure the device for the board. The config is written to the device on probe and on PM resume. Signed-off-by: Michael Drake Cc: Patrick Glaser Cc: Nate Case --- drivers/gpu/drm/bridge/ti949.c | 120 +++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/drivers/gpu/drm/bridge/ti949.c b/drivers/gpu/drm/bridge/ti949.c index 04618ca5f25e..57dcecd10ace 100644 --- a/drivers/gpu/drm/bridge/ti949.c +++ b/drivers/gpu/drm/bridge/ti949.c @@ -19,6 +19,7 @@ #include #include #include +#include #include /* Number of times to try checking for device on bringup. */ @@ -127,10 +128,22 @@ enum ti949_reg { TI949_REG_TX_ID_5 = 0xF5, }; +/** + * struct ti949_reg_val - ti949 register value + * @addr: The address of the register + * @value: The initial value of the register + */ +struct ti949_reg_val { + u8 addr; + u8 value; +}; + /** * struct ti949_ctx - ti949 driver context * @i2c: Handle for the device's i2c client. * @regmap: Handle for the device's regmap. + * @config: Array of register values loaded from device properties. + * @config_len: Number of entries in config. * @reg_names: Array of regulator names, or NULL. * @regs: Array of regulators, or NULL. * @reg_count: Number of entries in reg_names and regs arrays. @@ -138,6 +151,8 @@ enum ti949_reg { struct ti949_ctx { struct i2c_client *i2c; struct regmap *regmap; + struct ti949_reg_val *config; + size_t config_len; const char **reg_names; struct regulator **regs; size_t reg_count; @@ -214,6 +229,42 @@ static const struct regmap_config ti949_regmap_config = { .writeable_reg = ti949_writeable_reg, }; +static int ti949_write_sequence( + struct ti949_ctx *ti949, + const struct ti949_reg_val *sequence, + u32 entries) +{ + int i; + + for (i = 0; i < entries; i++) { + const struct ti949_reg_val *r = sequence + i; + int ret = regmap_write(ti949->regmap, r->addr, r->value); + + if (ret < 0) + return ret; + } + + return 0; +} + +static int ti949_write_config_seq(struct ti949_ctx *ti949) +{ + int ret; + + if (ti949->config == NULL) { + dev_info(&ti949->i2c->dev, "No config for ti949 device\n"); + return 0; + } + + ret = ti949_write_sequence(ti949, ti949->config, ti949->config_len); + if (ret < 0) + return ret; + + dev_info(&ti949->i2c->dev, "Successfully configured ti949\n"); + + return ret; +} + static inline u8 ti949_device_address(struct ti949_ctx *ti949) { return ti949->i2c->addr; @@ -347,6 +398,12 @@ static int ti949_pm_resume(struct device *dev) if (ret != 0) return ret; + ret = ti949_write_config_seq(ti949); + if (ret != 0) + return ret; + + /* Extend 200ms after ti949 init for display HW tolerance. */ + msleep(200); return 0; } @@ -436,6 +493,65 @@ static int ti949_get_regulators(struct ti949_ctx *ti949) return 0; } +static int ti949_get_config(struct ti949_ctx *ti949) +{ + int i; + int ret; + u8 *config; + size_t config_len; + + ret = device_property_read_u8_array(&ti949->i2c->dev, + "config", NULL, 0); + if (ret == -EINVAL || + ret == -ENODATA || + ret == 0) { + /* "config" property was either: + * - unset + * - valueless + * - set to empty list + * Not an error; continue without config. + */ + dev_info(&ti949->i2c->dev, "No config defined for device.\n"); + return 0; + + } else if (ret < 0) { + return ret; + } else if (ret & 0x1) { + dev_err(&ti949->i2c->dev, + "Device property 'config' needs even entry count.\n"); + return -EINVAL; + } + + config_len = ret; + + config = kmalloc_array(config_len, sizeof(*config), GFP_KERNEL); + if (!config) + return -ENOMEM; + + ret = device_property_read_u8_array(&ti949->i2c->dev, "config", + config, config_len); + if (ret < 0) { + kfree(config); + return ret; + } + + ti949->config = devm_kmalloc_array(&ti949->i2c->dev, + config_len / 2, sizeof(*ti949->config), GFP_KERNEL); + if (!ti949->config) { + kfree(config); + return -ENOMEM; + } + + ti949->config_len = config_len / 2; + for (i = 0; i < config_len; i += 2) { + ti949->config[i / 2].addr = config[i]; + ti949->config[i / 2].value = config[i + 1]; + } + kfree(config); + + return 0; +} + static int ti949_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -458,6 +574,10 @@ static int ti949_probe(struct i2c_client *client, if (ret != 0) return ret; + ret = ti949_get_config(ti949); + if (ret != 0) + return ret; + i2c_set_clientdata(client, ti949); ret = ti949_pm_resume(&client->dev); -- 2.20.1