aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorTomi Valkeinen <tomi.valkeinen@nokia.com>2010-06-09 08:24:46 -0400
committerTomi Valkeinen <tomi.valkeinen@nokia.com>2010-08-03 08:18:49 -0400
commitc8cd4547dcb350331cf80f5729ee648d8120783e (patch)
treedf619859423dc15becec418836c9b0debe70c4ec /drivers/video
parent0f45bddf0420ace2ddb7c4faa11f139b42c6eea5 (diff)
OMAP: DSS2: Taal: Add regulator configuration support
Add support for configuring regulators in the panel specific configuration data. Signed-off-by: Jani Nikula <ext-jani.1.nikula@nokia.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@nokia.com>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/omap2/displays/panel-taal.c83
1 files changed, 83 insertions, 0 deletions
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index cbe0214e2f05..941f1f208c9e 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -30,6 +30,7 @@
30#include <linux/gpio.h> 30#include <linux/gpio.h>
31#include <linux/workqueue.h> 31#include <linux/workqueue.h>
32#include <linux/slab.h> 32#include <linux/slab.h>
33#include <linux/regulator/consumer.h>
33#include <linux/mutex.h> 34#include <linux/mutex.h>
34 35
35#include <plat/display.h> 36#include <plat/display.h>
@@ -68,6 +69,73 @@ static irqreturn_t taal_te_isr(int irq, void *data);
68static void taal_te_timeout_work_callback(struct work_struct *work); 69static void taal_te_timeout_work_callback(struct work_struct *work);
69static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable); 70static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable);
70 71
72struct panel_regulator {
73 struct regulator *regulator;
74 const char *name;
75 int min_uV;
76 int max_uV;
77};
78
79static void free_regulators(struct panel_regulator *regulators, int n)
80{
81 int i;
82
83 for (i = 0; i < n; i++) {
84 /* disable/put in reverse order */
85 regulator_disable(regulators[n - i - 1].regulator);
86 regulator_put(regulators[n - i - 1].regulator);
87 }
88}
89
90static int init_regulators(struct omap_dss_device *dssdev,
91 struct panel_regulator *regulators, int n)
92{
93 int r, i, v;
94
95 for (i = 0; i < n; i++) {
96 struct regulator *reg;
97
98 reg = regulator_get(&dssdev->dev, regulators[i].name);
99 if (IS_ERR(reg)) {
100 dev_err(&dssdev->dev, "failed to get regulator %s\n",
101 regulators[i].name);
102 r = PTR_ERR(reg);
103 goto err;
104 }
105
106 /* FIXME: better handling of fixed vs. variable regulators */
107 v = regulator_get_voltage(reg);
108 if (v < regulators[i].min_uV || v > regulators[i].max_uV) {
109 r = regulator_set_voltage(reg, regulators[i].min_uV,
110 regulators[i].max_uV);
111 if (r) {
112 dev_err(&dssdev->dev,
113 "failed to set regulator %s voltage\n",
114 regulators[i].name);
115 regulator_put(reg);
116 goto err;
117 }
118 }
119
120 r = regulator_enable(reg);
121 if (r) {
122 dev_err(&dssdev->dev, "failed to enable regulator %s\n",
123 regulators[i].name);
124 regulator_put(reg);
125 goto err;
126 }
127
128 regulators[i].regulator = reg;
129 }
130
131 return 0;
132
133err:
134 free_regulators(regulators, i);
135
136 return r;
137}
138
71/** 139/**
72 * struct panel_config - panel configuration 140 * struct panel_config - panel configuration
73 * @name: panel name 141 * @name: panel name
@@ -75,6 +143,8 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable);
75 * @timings: panel resolution 143 * @timings: panel resolution
76 * @sleep: various panel specific delays, passed to msleep() if non-zero 144 * @sleep: various panel specific delays, passed to msleep() if non-zero
77 * @reset_sequence: reset sequence timings, passed to udelay() if non-zero 145 * @reset_sequence: reset sequence timings, passed to udelay() if non-zero
146 * @regulators: array of panel regulators
147 * @num_regulators: number of regulators in the array
78 */ 148 */
79struct panel_config { 149struct panel_config {
80 const char *name; 150 const char *name;
@@ -93,6 +163,9 @@ struct panel_config {
93 unsigned int high; 163 unsigned int high;
94 unsigned int low; 164 unsigned int low;
95 } reset_sequence; 165 } reset_sequence;
166
167 struct panel_regulator *regulators;
168 int num_regulators;
96}; 169};
97 170
98enum { 171enum {
@@ -629,6 +702,11 @@ static int taal_probe(struct omap_dss_device *dssdev)
629 702
630 atomic_set(&td->do_update, 0); 703 atomic_set(&td->do_update, 0);
631 704
705 r = init_regulators(dssdev, panel_config->regulators,
706 panel_config->num_regulators);
707 if (r)
708 goto err_reg;
709
632 td->esd_wq = create_singlethread_workqueue("taal_esd"); 710 td->esd_wq = create_singlethread_workqueue("taal_esd");
633 if (td->esd_wq == NULL) { 711 if (td->esd_wq == NULL) {
634 dev_err(&dssdev->dev, "can't create ESD workqueue\n"); 712 dev_err(&dssdev->dev, "can't create ESD workqueue\n");
@@ -714,6 +792,8 @@ err_gpio:
714err_bl: 792err_bl:
715 destroy_workqueue(td->esd_wq); 793 destroy_workqueue(td->esd_wq);
716err_wq: 794err_wq:
795 free_regulators(panel_config->regulators, panel_config->num_regulators);
796err_reg:
717 kfree(td); 797 kfree(td);
718err: 798err:
719 return r; 799 return r;
@@ -746,6 +826,9 @@ static void taal_remove(struct omap_dss_device *dssdev)
746 /* reset, to be sure that the panel is in a valid state */ 826 /* reset, to be sure that the panel is in a valid state */
747 taal_hw_reset(dssdev); 827 taal_hw_reset(dssdev);
748 828
829 free_regulators(td->panel_config->regulators,
830 td->panel_config->num_regulators);
831
749 kfree(td); 832 kfree(td);
750} 833}
751 834