From patchwork Wed May 5 14:27:40 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jani Nikula X-Patchwork-Id: 97114 X-Patchwork-Delegate: tomi.valkeinen@nokia.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o45ESTjf002812 for ; Wed, 5 May 2010 14:28:29 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S934849Ab0EEO2U (ORCPT ); Wed, 5 May 2010 10:28:20 -0400 Received: from smtp.nokia.com ([192.100.105.134]:34140 "EHLO mgw-mx09.nokia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934836Ab0EEO2P (ORCPT ); Wed, 5 May 2010 10:28:15 -0400 Received: from esebh106.NOE.Nokia.com (esebh106.ntc.nokia.com [172.21.138.213]) by mgw-mx09.nokia.com (Switch-3.3.3/Switch-3.3.3) with ESMTP id o45ES7Jw005951; Wed, 5 May 2010 09:28:13 -0500 Received: from esebh102.NOE.Nokia.com ([172.21.138.183]) by esebh106.NOE.Nokia.com with Microsoft SMTPSVC(6.0.3790.3959); Wed, 5 May 2010 17:28:12 +0300 Received: from mgw-sa02.ext.nokia.com ([147.243.1.48]) by esebh102.NOE.Nokia.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.3959); Wed, 5 May 2010 17:28:12 +0300 Received: from localhost.localdomain (esdhcp04142.research.nokia.com [172.21.41.42]) by mgw-sa02.ext.nokia.com (Switch-3.3.3/Switch-3.3.3) with ESMTP id o45ERfRM016232; Wed, 5 May 2010 17:28:11 +0300 From: Jani Nikula To: Tomi.Valkeinen@nokia.com, tony@atomide.com Cc: linux-omap@vger.kernel.org, linux-fbdev@vger.kernel.org, ext-jani.1.nikula@nokia.com Subject: [PATCH v3 20/21] OMAP: DSS2: Taal: Add regulator configuration support Date: Wed, 5 May 2010 17:27:40 +0300 Message-Id: <1b93af2daf403f2fe822469b71c12ea7eb1cc68a.1273067195.git.ext-jani.1.nikula@nokia.com> X-Mailer: git-send-email 1.6.5.2 In-Reply-To: <5e7384699d72bad3865dc9604b18ad05775bfb27.1273067195.git.ext-jani.1.nikula@nokia.com> References: <1dfb7728d4d3ba8ceff808563e5a9f4c40aa3e9f.1273067195.git.ext-jani.1.nikula@nokia.com> <6b813e9f0008e23e7981f6ca35501f56c292858a.1273067195.git.ext-jani.1.nikula@nokia.com> <94d9d7bebbf7588bd77b65e6a46044240140a350.1273067195.git.ext-jani.1.nikula@nokia.com> <61a89461654fe44174902f6e29b8acded7529b67.1273067195.git.ext-jani.1.nikula@nokia.com> <16a98ca1b45ba9b9bb30f23d242449c1d440df07.1273067195.git.ext-jani.1.nikula@nokia.com> <0cfff2a3cbb4231b41b382caf8aab7c52f47b0d5.1273067195.git.ext-jani.1.nikula@nokia.com> <4cb510ffbc3216e2a7dac16edaff5fb1980b3315.1273067195.git.ext-jani.1.nikula@nokia.com> <8665676eca5bbd3be35b63f7110f629e94a6babe.1273067195.git.ext-jani.1.nikula@nokia.com> <4f2a95d67d2b8004f4a2055681690920ebeb8e8f.1273067195.git.ext-jani.1.nikula@nokia.com> <690ef5c45aee3fb87a40fa03039356f8238925dc.1273067195.git.ext-jani.1.nikula@nokia.com> <025c12267d4bd88e1f59d9e13aafec247fe3c730.1273067195.git.ext-jani.1.nikula@nokia.com> <5e7384699d72bad3865dc9604b18ad05775bfb27.1273067195.git.ext-jani.1.nikula@nokia.com> In-Reply-To: References: X-OriginalArrivalTime: 05 May 2010 14:28:12.0240 (UTC) FILETIME=[310C0500:01CAEC5F] X-Nokia-AV: Clean Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Wed, 05 May 2010 14:28:33 +0000 (UTC) diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index b73cd12..617723b 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -68,6 +69,73 @@ static irqreturn_t taal_te_isr(int irq, void *data); static void taal_te_timeout_work_callback(struct work_struct *work); static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable); +struct panel_regulator { + struct regulator *regulator; + const char *name; + int min_uV; + int max_uV; +}; + +static void free_regulators(struct panel_regulator *regulators, int n) +{ + int i; + + for (i = 0; i < n; i++) { + /* disable/put in reverse order */ + regulator_disable(regulators[n - i - 1].regulator); + regulator_put(regulators[n - i - 1].regulator); + } +} + +static int init_regulators(struct omap_dss_device *dssdev, + struct panel_regulator *regulators, int n) +{ + int r, i, v; + + for (i = 0; i < n; i++) { + struct regulator *reg; + + reg = regulator_get(&dssdev->dev, regulators[i].name); + if (IS_ERR(reg)) { + dev_err(&dssdev->dev, "failed to get regulator %s\n", + regulators[i].name); + r = PTR_ERR(reg); + goto err; + } + + /* FIXME: better handling of fixed vs. variable regulators */ + v = regulator_get_voltage(reg); + if (v < regulators[i].min_uV || v > regulators[i].max_uV) { + r = regulator_set_voltage(reg, regulators[i].min_uV, + regulators[i].max_uV); + if (r) { + dev_err(&dssdev->dev, + "failed to set regulator %s voltage\n", + regulators[i].name); + regulator_put(reg); + goto err; + } + } + + r = regulator_enable(reg); + if (r) { + dev_err(&dssdev->dev, "failed to enable regulator %s\n", + regulators[i].name); + regulator_put(reg); + goto err; + } + + regulators[i].regulator = reg; + } + + return 0; + +err: + free_regulators(regulators, i); + + return r; +} + /** * struct panel_config - panel configuration * @name: panel name @@ -75,6 +143,8 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable); * @timings: panel resolution * @sleep: various panel specific delays, passed to msleep() if non-zero * @reset_sequence: reset sequence timings, passed to udelay() if non-zero + * @regulators: array of panel regulators + * @num_regulators: number of regulators in the array */ struct panel_config { const char *name; @@ -93,6 +163,9 @@ struct panel_config { unsigned int high; unsigned int low; } reset_sequence; + + struct panel_regulator *regulators; + int num_regulators; }; enum { @@ -629,6 +702,11 @@ static int taal_probe(struct omap_dss_device *dssdev) atomic_set(&td->do_update, 0); + r = init_regulators(dssdev, panel_config->regulators, + panel_config->num_regulators); + if (r) + goto err_reg; + td->esd_wq = create_singlethread_workqueue("taal_esd"); if (td->esd_wq == NULL) { dev_err(&dssdev->dev, "can't create ESD workqueue\n"); @@ -714,6 +792,8 @@ err_gpio: err_bl: destroy_workqueue(td->esd_wq); err_wq: + free_regulators(panel_config->regulators, panel_config->num_regulators); +err_reg: kfree(td); err: return r; @@ -746,6 +826,9 @@ static void taal_remove(struct omap_dss_device *dssdev) /* reset, to be sure that the panel is in a valid state */ taal_hw_reset(dssdev); + free_regulators(td->panel_config->regulators, + td->panel_config->num_regulators); + kfree(td); }