From patchwork Thu Mar 7 13:17:47 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Lartey X-Patchwork-Id: 2231841 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork1.kernel.org (Postfix) with ESMTP id B15443FC8F for ; Thu, 7 Mar 2013 13:24:04 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UDajB-0003uT-Fd; Thu, 07 Mar 2013 13:19:26 +0000 Received: from slimlogic.co.uk ([89.16.172.20]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1UDaiF-0003hB-Pe for linux-arm-kernel@lists.infradead.org; Thu, 07 Mar 2013 13:18:30 +0000 Received: from localhost.localdomain (cpc1-sgyl22-0-0-cust5.sgyl.cable.virginmedia.com [92.235.204.6]) by slimlogic.co.uk (Postfix) with ESMTPSA id 1D180130A16; Thu, 7 Mar 2013 13:18:22 +0000 (GMT) From: Ian Lartey To: linux-kernel@vger.kernel.org Subject: [PATCH v8 03/12] mfd: palmas add variant and OTP detection Date: Thu, 7 Mar 2013 13:17:47 +0000 Message-Id: <1362662276-20792-3-git-send-email-ian@slimlogic.co.uk> X-Mailer: git-send-email 1.7.0.4 In-Reply-To: <1362662276-20792-1-git-send-email-ian@slimlogic.co.uk> References: <1362662276-20792-1-git-send-email-ian@slimlogic.co.uk> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130307_081824_218513_D511BF7D X-CRM114-Status: GOOD ( 21.63 ) X-Spam-Score: -2.5 (--) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-2.5 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.6 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: t-kristo@ti.com, broonie@opensource.wolfsonmicro.com, mturquette@linaro.org, linux-watchdog@vger.kernel.org, swarren@wwwdotorg.org, j-keerthy@ti.com, linus.walleij@linaro.org, linux-doc@vger.kernel.org, lgirdwood@gmail.com, rob.herring@calxeda.com, grant.likely@secretlab.ca, wim@iguana.be, ldewangan@nvidia.com, rpurdie@rpsys.net, linux-arm-kernel@lists.infradead.org, rob@landley.net, cooloney@gmail.com, gg@slimlogic.co.uk, Ian Lartey , linux-leds@vger.kernel.org, sameo@linux.intel.com X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org From: Graeme Gregory Read the chip varient and the OTP information from the chip and display this on probe to aid in debugging of issues. Older palmas chips do not have the USB_ID programmed and will therefore return 0x0000 for this field. palmas register read/write/update API is now used palmas_read_product_id_and_revs used by palmas_i2c_probe to get the device id, design and software revisions id field of pamas struct renamed to device_id Updated the DT parsing to agree with the bindings document, just some minor value name changes. Signed-off-by: Graeme Gregory Signed-off-by: Ian Lartey --- drivers/mfd/palmas.c | 103 ++++++++++++++++++++++++++++++++++---------- include/linux/mfd/palmas.h | 35 ++++++++++++++- 2 files changed, 114 insertions(+), 24 deletions(-) diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c index bbdbc50..9d1adfe 100644 --- a/drivers/mfd/palmas.c +++ b/drivers/mfd/palmas.c @@ -1,9 +1,10 @@ /* * TI Palmas MFD Driver * - * Copyright 2011-2012 Texas Instruments Inc. + * Copyright 2011-2013 Texas Instruments Inc. * * Author: Graeme Gregory + * Author: Ian Lartey * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -257,26 +258,76 @@ static struct regmap_irq_chip palmas_irq_chip = { PALMAS_INT1_MASK), }; +static int palmas_read_product_id_and_revs(struct palmas *palmas) +{ + int ret; + unsigned int reg; + + /* Read variant info from the device */ + ret = palmas_read(palmas, PALMAS_ID_BASE, PALMAS_PRODUCT_ID_LSB, ®); + if (ret < 0) { + dev_err(palmas->dev, "Unable to read ID err: %d\n", ret); + return ret; + } + + palmas->product_id = reg; + + ret = palmas_read(palmas, PALMAS_ID_BASE, PALMAS_PRODUCT_ID_MSB, ®); + if (ret < 0) { + dev_err(palmas->dev, "Unable to read ID err: %d\n", ret); + return ret; + } + + palmas->product_id |= reg << 8; + + dev_info(palmas->dev, "Product ID %x\n", palmas->product_id); + + ret = palmas_read(palmas, PALMAS_DESIGNREV_BASE, + PALMAS_DESIGNREV, ®); + if (ret < 0) { + dev_err(palmas->dev, "Unable to read DESIGNREV err: %d\n", ret); + return ret; + } + + palmas->designrev = reg & PALMAS_DESIGNREV_DESIGNREV_MASK; + + dev_info(palmas->dev, "Product Design Rev %x\n", palmas->designrev); + + ret = palmas_read(palmas, PALMAS_PMU_CONTROL_BASE, PALMAS_SW_REVISION, + ®); + if (ret < 0) { + dev_err(palmas->dev, "Unable to read SW_REVISION err: %d\n", + ret); + return ret; + } + + palmas->sw_revision = reg; + + dev_info(palmas->dev, "Product SW Rev %x\n", palmas->sw_revision); + + return 0; +} + static void palmas_dt_to_pdata(struct device_node *node, struct palmas_platform_data *pdata) { int ret; u32 prop; - ret = of_property_read_u32(node, "ti,mux_pad1", &prop); + ret = of_property_read_u32(node, "ti,mux-pad1", &prop); if (!ret) { pdata->mux_from_pdata = 1; pdata->pad1 = prop; } - ret = of_property_read_u32(node, "ti,mux_pad2", &prop); + ret = of_property_read_u32(node, "ti,mux-pad2", &prop); if (!ret) { pdata->mux_from_pdata = 1; pdata->pad2 = prop; } /* The default for this register is all masked */ - ret = of_property_read_u32(node, "ti,power_ctrl", &prop); + ret = of_property_read_u32(node, "ti,power-ctrl", &prop); if (!ret) pdata->power_ctrl = prop; else @@ -292,7 +343,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c, struct palmas_platform_data *pdata; struct device_node *node = i2c->dev.of_node; int ret = 0, i; - unsigned int reg, addr; + unsigned int reg; int slave; struct mfd_cell *children; @@ -316,7 +367,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c, i2c_set_clientdata(i2c, palmas); palmas->dev = &i2c->dev; - palmas->id = id->driver_data; + palmas->product_id = id->driver_data; palmas->irq = i2c->irq; for (i = 0; i < PALMAS_NUM_CLIENTS; i++) { @@ -344,12 +395,16 @@ static int palmas_i2c_probe(struct i2c_client *i2c, } } + /* Read variant info from the device */ + ret = palmas_read_product_id_and_revs(palmas); + if (ret < 0) + goto err; + /* Change IRQ into clear on read mode for efficiency */ slave = PALMAS_BASE_TO_SLAVE(PALMAS_INTERRUPT_BASE); - addr = PALMAS_BASE_TO_REG(PALMAS_INTERRUPT_BASE, PALMAS_INT_CTRL); reg = PALMAS_INT_CTRL_INT_CLEAR; - regmap_write(palmas->regmap[slave], addr, reg); + ret = palmas_write(palmas, PALMAS_INTERRUPT_BASE, PALMAS_INT_CTRL, reg); ret = regmap_add_irq_chip(palmas->regmap[slave], palmas->irq, IRQF_ONESHOT | IRQF_TRIGGER_LOW, 0, &palmas_irq_chip, @@ -357,17 +412,15 @@ static int palmas_i2c_probe(struct i2c_client *i2c, if (ret < 0) goto err; - slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE); - addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE, - PALMAS_PRIMARY_SECONDARY_PAD1); - if (pdata->mux_from_pdata) { reg = pdata->pad1; - ret = regmap_write(palmas->regmap[slave], addr, reg); + ret = palmas_write(palmas, PALMAS_PU_PD_OD_BASE, + PALMAS_PRIMARY_SECONDARY_PAD1, reg); if (ret) goto err_irq; } else { - ret = regmap_read(palmas->regmap[slave], addr, ®); + ret = palmas_read(palmas, PALMAS_PU_PD_OD_BASE, + PALMAS_PRIMARY_SECONDARY_PAD1, ®); if (ret) goto err_irq; } @@ -393,16 +446,15 @@ static int palmas_i2c_probe(struct i2c_client *i2c, if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_3)) palmas->gpio_muxed |= PALMAS_GPIO_3_MUXED; - addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE, - PALMAS_PRIMARY_SECONDARY_PAD2); - if (pdata->mux_from_pdata) { reg = pdata->pad2; - ret = regmap_write(palmas->regmap[slave], addr, reg); + ret = palmas_write(palmas, PALMAS_PU_PD_OD_BASE, + PALMAS_PRIMARY_SECONDARY_PAD2, reg); if (ret) goto err_irq; } else { - ret = regmap_read(palmas->regmap[slave], addr, ®); + ret = palmas_read(palmas, PALMAS_PU_PD_OD_BASE, + PALMAS_PRIMARY_SECONDARY_PAD2, ®); if (ret) goto err_irq; } @@ -422,10 +474,8 @@ static int palmas_i2c_probe(struct i2c_client *i2c, reg = pdata->power_ctrl; - slave = PALMAS_BASE_TO_SLAVE(PALMAS_PMU_CONTROL_BASE); - addr = PALMAS_BASE_TO_REG(PALMAS_PMU_CONTROL_BASE, PALMAS_POWER_CTRL); - - ret = regmap_write(palmas->regmap[slave], addr, reg); + ret = palmas_write(palmas, PALMAS_PU_PD_OD_BASE, + PALMAS_PRIMARY_SECONDARY_PAD2, reg); if (ret) goto err_irq; @@ -504,6 +554,13 @@ MODULE_DEVICE_TABLE(i2c, palmas_i2c_id); static struct of_device_id of_palmas_match_tbl[] = { { .compatible = "ti,palmas", }, + { .compatible = "ti,palmas-charger", }, + { .compatible = "ti,twl6035", }, + { .compatible = "ti,twl6036", }, + { .compatible = "ti,twl6037", }, + { .compatible = "ti,tps65913", }, + { .compatible = "ti,tps65914", }, + { .compatible = "ti,tps80036", }, { /* end */ } }; diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h index f66ef32..0427165 100644 --- a/include/linux/mfd/palmas.h +++ b/include/linux/mfd/palmas.h @@ -44,7 +44,9 @@ struct palmas { struct regmap *regmap[PALMAS_NUM_CLIENTS]; /* Stored chip id */ - int id; + int product_id; + int designrev; + int sw_revision; /* IRQ Data */ int irq; @@ -437,11 +439,13 @@ enum usb_irq_events { #define PALMAS_PU_PD_OD_BASE 0x1F4 #define PALMAS_LED_BASE 0x200 #define PALMAS_INTERRUPT_BASE 0x210 +#define PALMAS_ID_BASE 0x24F #define PALMAS_USB_OTG_BASE 0x250 #define PALMAS_VIBRATOR_BASE 0x270 #define PALMAS_GPIO_BASE 0x280 #define PALMAS_USB_BASE 0x290 #define PALMAS_GPADC_BASE 0x2C0 +#define PALMAS_DESIGNREV_BASE 0x357 #define PALMAS_TRIM_GPADC_BASE 0x3CD /* Registers for function RTC */ @@ -2159,6 +2163,28 @@ enum usb_irq_events { #define PALMAS_INT_CTRL_INT_CLEAR 0x01 #define PALMAS_INT_CTRL_INT_CLEAR_SHIFT 0 +/* Registers for function ID */ +#define PALMAS_VENDOR_ID_LSB 0x0 +#define PALMAS_VENDOR_ID_MSB 0x1 +#define PALMAS_PRODUCT_ID_LSB 0x2 +#define PALMAS_PRODUCT_ID_MSB 0x3 + +/* Bit definitions for VENDOR_ID_LSB */ +#define PALMAS_VENDOR_ID_LSB_VENDOR_ID_MASK 0xff +#define PALMAS_VENDOR_ID_LSB_VENDOR_ID_SHIFT 0 + +/* Bit definitions for VENDOR_ID_MSB */ +#define PALMAS_VENDOR_ID_MSB_VENDOR_ID_MASK 0xff +#define PALMAS_VENDOR_ID_MSB_VENDOR_ID_SHIFT 0 + +/* Bit definitions for PRODUCT_ID_LSB */ +#define PALMAS_PRODUCT_ID_LSB_PRODUCT_ID_MASK 0xff +#define PALMAS_PRODUCT_ID_LSB_PRODUCT_ID_SHIFT 0 + +/* Bit definitions for PRODUCT_ID_MSB */ +#define PALMAS_PRODUCT_ID_MSB_PRODUCT_ID_MASK 0xff +#define PALMAS_PRODUCT_ID_MSB_PRODUCT_ID_SHIFT 0 + /* Registers for function USB_OTG */ #define PALMAS_USB_WAKEUP 0x3 #define PALMAS_USB_VBUS_CTRL_SET 0x4 @@ -2781,6 +2807,13 @@ enum usb_irq_events { #define PALMAS_GPADC_SMPS_VSEL_MONITORING_SMPS_VSEL_MONITORING_MASK 0x7f #define PALMAS_GPADC_SMPS_VSEL_MONITORING_SMPS_VSEL_MONITORING_SHIFT 0 +/* Registers for function DESIGNREV */ +#define PALMAS_DESIGNREV 0x0 + +/* Bit definitions for DESIGNREV */ +#define PALMAS_DESIGNREV_DESIGNREV_MASK 0x0f +#define PALMAS_DESIGNREV_DESIGNREV_SHIFT 0 + /* Registers for function GPADC */ #define PALMAS_GPADC_TRIM1 0x0 #define PALMAS_GPADC_TRIM2 0x1