diff options
author | Tomi Valkeinen <tomi.valkeinen@nokia.com> | 2010-06-09 08:24:46 -0400 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@nokia.com> | 2010-08-03 08:18:49 -0400 |
commit | c8cd4547dcb350331cf80f5729ee648d8120783e (patch) | |
tree | df619859423dc15becec418836c9b0debe70c4ec /drivers | |
parent | 0f45bddf0420ace2ddb7c4faa11f139b42c6eea5 (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')
-rw-r--r-- | drivers/video/omap2/displays/panel-taal.c | 83 |
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); | |||
68 | static void taal_te_timeout_work_callback(struct work_struct *work); | 69 | static void taal_te_timeout_work_callback(struct work_struct *work); |
69 | static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable); | 70 | static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable); |
70 | 71 | ||
72 | struct panel_regulator { | ||
73 | struct regulator *regulator; | ||
74 | const char *name; | ||
75 | int min_uV; | ||
76 | int max_uV; | ||
77 | }; | ||
78 | |||
79 | static 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 | |||
90 | static 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 | |||
133 | err: | ||
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 | */ |
79 | struct panel_config { | 149 | struct 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 | ||
98 | enum { | 171 | enum { |
@@ -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: | |||
714 | err_bl: | 792 | err_bl: |
715 | destroy_workqueue(td->esd_wq); | 793 | destroy_workqueue(td->esd_wq); |
716 | err_wq: | 794 | err_wq: |
795 | free_regulators(panel_config->regulators, panel_config->num_regulators); | ||
796 | err_reg: | ||
717 | kfree(td); | 797 | kfree(td); |
718 | err: | 798 | err: |
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 | ||