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>
This commit is contained in:
Родитель
0f45bddf04
Коммит
c8cd4547dc
|
@ -30,6 +30,7 @@
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
#include <linux/regulator/consumer.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
|
|
||||||
#include <plat/display.h>
|
#include <plat/display.h>
|
||||||
|
@ -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 void taal_te_timeout_work_callback(struct work_struct *work);
|
||||||
static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable);
|
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
|
* struct panel_config - panel configuration
|
||||||
* @name: panel name
|
* @name: panel name
|
||||||
|
@ -75,6 +143,8 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable);
|
||||||
* @timings: panel resolution
|
* @timings: panel resolution
|
||||||
* @sleep: various panel specific delays, passed to msleep() if non-zero
|
* @sleep: various panel specific delays, passed to msleep() if non-zero
|
||||||
* @reset_sequence: reset sequence timings, passed to udelay() 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 {
|
struct panel_config {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
@ -93,6 +163,9 @@ struct panel_config {
|
||||||
unsigned int high;
|
unsigned int high;
|
||||||
unsigned int low;
|
unsigned int low;
|
||||||
} reset_sequence;
|
} reset_sequence;
|
||||||
|
|
||||||
|
struct panel_regulator *regulators;
|
||||||
|
int num_regulators;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -629,6 +702,11 @@ static int taal_probe(struct omap_dss_device *dssdev)
|
||||||
|
|
||||||
atomic_set(&td->do_update, 0);
|
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");
|
td->esd_wq = create_singlethread_workqueue("taal_esd");
|
||||||
if (td->esd_wq == NULL) {
|
if (td->esd_wq == NULL) {
|
||||||
dev_err(&dssdev->dev, "can't create ESD workqueue\n");
|
dev_err(&dssdev->dev, "can't create ESD workqueue\n");
|
||||||
|
@ -714,6 +792,8 @@ err_gpio:
|
||||||
err_bl:
|
err_bl:
|
||||||
destroy_workqueue(td->esd_wq);
|
destroy_workqueue(td->esd_wq);
|
||||||
err_wq:
|
err_wq:
|
||||||
|
free_regulators(panel_config->regulators, panel_config->num_regulators);
|
||||||
|
err_reg:
|
||||||
kfree(td);
|
kfree(td);
|
||||||
err:
|
err:
|
||||||
return r;
|
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 */
|
/* reset, to be sure that the panel is in a valid state */
|
||||||
taal_hw_reset(dssdev);
|
taal_hw_reset(dssdev);
|
||||||
|
|
||||||
|
free_regulators(td->panel_config->regulators,
|
||||||
|
td->panel_config->num_regulators);
|
||||||
|
|
||||||
kfree(td);
|
kfree(td);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче