aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJimmy Rubin <jimmy.rubin@stericsson.com>2011-09-29 14:55:00 +0200
committerRobert Marklund <robert.marklund@stericsson.com>2011-10-27 16:08:46 +0200
commitab193cbc346ef47d361b579a2f3095cae2c837dc (patch)
treec063d7ab7378b62dd38a40f89253d6a4e42c22af
parentfd5871b1deb2c11a53557ecf76a3dc14f8feb636 (diff)
video: mcde: Move driver data to sony display
Some driver data that are located in the board file should be filled in by the display driver instead ST-Ericsson ID: 321190 ST-Ericsson Linux next: NA ST-Ericsson FOSS-OUT ID: Trivial Change-Id: I564462d9806cfde90de25ff436e0d4946682ef23 Signed-off-by: Jimmy Rubin <jimmy.rubin@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/32595 Reviewed-by: QABUILD Reviewed-by: Marcus LORENTZON <marcus.xm.lorentzon@stericsson.com>
-rw-r--r--drivers/video/mcde/display-sony_acx424akp_dsi.c295
-rw-r--r--include/video/mcde_display-sony_acx424akp_dsi.h2
2 files changed, 148 insertions, 149 deletions
diff --git a/drivers/video/mcde/display-sony_acx424akp_dsi.c b/drivers/video/mcde/display-sony_acx424akp_dsi.c
index 3cad2b9718e..aace9ff94f2 100644
--- a/drivers/video/mcde/display-sony_acx424akp_dsi.c
+++ b/drivers/video/mcde/display-sony_acx424akp_dsi.c
@@ -14,10 +14,31 @@
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/err.h>
+#include <linux/slab.h>
+
+#include <linux/regulator/consumer.h>
#include <video/mcde_display.h>
#include <video/mcde_display-sony_acx424akp_dsi.h>
+#define RESET_DELAY_MS 11
+#define RESET_LOW_DELAY_US 20
+#define SLEEP_OUT_DELAY_MS 140
+#define IO_REGU "vddi"
+#define IO_REGU_MIN 1600000
+#define IO_REGU_MAX 3300000
+
+struct device_info {
+ int reset_gpio;
+ struct mcde_port port;
+ struct regulator *regulator;
+};
+
+static inline struct device_info *get_drvdata(struct mcde_display_device *ddev)
+{
+ return (struct device_info *)dev_get_drvdata(&ddev->dev);
+}
+
static int display_read_deviceid(struct mcde_display_device *dev, u16 *id)
{
struct mcde_chnl_state *chnl;
@@ -58,50 +79,62 @@ out:
return 0;
}
-static int sony_acx424akp_platform_enable(struct mcde_display_device *dev)
+static int power_on(struct mcde_display_device *dev)
{
- struct mcde_display_sony_acx424akp_platform_data *pdata =
- dev->dev.platform_data;
+ struct device_info *di = get_drvdata(dev);
dev_dbg(&dev->dev, "%s: Reset & power on sony display\n", __func__);
- if (pdata->regulator) {
- if (regulator_enable(pdata->regulator) < 0) {
- dev_err(&dev->dev, "%s:Failed to enable regulator\n"
- , __func__);
- return -EINVAL;
- }
- }
- if (pdata->reset_gpio)
- gpio_set_value(pdata->reset_gpio, pdata->reset_high);
- msleep(pdata->reset_delay); /* as per sony lcd spec */
- if (pdata->reset_gpio)
- gpio_set_value(pdata->reset_gpio, !pdata->reset_high);
- msleep(pdata->reset_low_delay); /* as per sony lcd spec */
- if (pdata->reset_gpio)
- gpio_set_value(pdata->reset_gpio, pdata->reset_high);
- msleep(pdata->reset_delay); /* as per sony lcd spec */
+ regulator_enable(di->regulator);
+ gpio_set_value_cansleep(di->reset_gpio, 0);
+ udelay(RESET_LOW_DELAY_US);
+ gpio_set_value_cansleep(di->reset_gpio, 1);
+ msleep(RESET_DELAY_MS);
return 0;
}
-static int sony_acx424akp_platform_disable(struct mcde_display_device *dev)
+static int power_off(struct mcde_display_device *dev)
{
- struct mcde_display_sony_acx424akp_platform_data *pdata =
- dev->dev.platform_data;
+ struct device_info *di = get_drvdata(dev);
dev_dbg(&dev->dev, "%s:Reset & power off sony display\n", __func__);
- if (pdata->regulator) {
- if (regulator_disable(pdata->regulator) < 0) {
- dev_err(&dev->dev, "%s:Failed to disable regulator\n"
- , __func__);
- return -EINVAL;
- }
- }
+ regulator_disable(di->regulator);
+
return 0;
}
+static int display_on(struct mcde_display_device *ddev)
+{
+ int ret;
+
+ dev_dbg(&ddev->dev, "Display on sony display\n");
+
+ ret = mcde_dsi_dcs_write(ddev->chnl_state, DCS_CMD_EXIT_SLEEP_MODE,
+ NULL, 0);
+ if (ret)
+ return ret;
+ msleep(SLEEP_OUT_DELAY_MS);
+ return mcde_dsi_dcs_write(ddev->chnl_state, DCS_CMD_SET_DISPLAY_ON,
+ NULL, 0);
+}
+
+static int display_off(struct mcde_display_device *ddev)
+{
+ int ret;
+
+ dev_dbg(&ddev->dev, "Display off sony display\n");
+
+ ret = mcde_dsi_dcs_write(ddev->chnl_state, DCS_CMD_SET_DISPLAY_OFF,
+ NULL, 0);
+ if (ret)
+ return ret;
+
+ return mcde_dsi_dcs_write(ddev->chnl_state, DCS_CMD_ENTER_SLEEP_MODE,
+ NULL, 0);
+}
+
static int sony_acx424akp_set_scan_mode(struct mcde_display_device *ddev,
enum mcde_display_power_mode power_mode)
{
@@ -148,187 +181,155 @@ static int sony_acx424akp_set_power_mode(struct mcde_display_device *ddev,
enum mcde_display_power_mode power_mode)
{
int ret = 0;
- struct mcde_display_sony_acx424akp_platform_data *pdata =
- ddev->dev.platform_data;
dev_dbg(&ddev->dev, "%s:Set Power mode\n", __func__);
/* OFF -> STANDBY */
if (ddev->power_mode == MCDE_DISPLAY_PM_OFF &&
- power_mode != MCDE_DISPLAY_PM_OFF) {
-
- if (ddev->platform_enable) {
- ret = ddev->platform_enable(ddev);
- if (ret)
- return ret;
- }
-
+ power_mode != MCDE_DISPLAY_PM_OFF) {
+ ret = power_on(ddev);
+ if (ret)
+ return ret;
ddev->power_mode = MCDE_DISPLAY_PM_STANDBY;
}
/* STANDBY -> ON */
if (ddev->power_mode == MCDE_DISPLAY_PM_STANDBY &&
- power_mode == MCDE_DISPLAY_PM_ON) {
-
- ret = mcde_dsi_dcs_write(ddev->chnl_state,
- DCS_CMD_EXIT_SLEEP_MODE, NULL, 0);
- if (ret)
- return ret;
+ power_mode == MCDE_DISPLAY_PM_ON) {
- msleep(pdata->sleep_out_delay);
-
- ret = mcde_dsi_dcs_write(ddev->chnl_state,
- DCS_CMD_SET_DISPLAY_ON, NULL, 0);
+ ret = display_on(ddev);
if (ret)
return ret;
-
ddev->power_mode = MCDE_DISPLAY_PM_ON;
- goto set_power_and_exit;
}
/* ON -> STANDBY */
else if (ddev->power_mode == MCDE_DISPLAY_PM_ON &&
- power_mode <= MCDE_DISPLAY_PM_STANDBY) {
- ret = mcde_dsi_dcs_write(ddev->chnl_state,
- DCS_CMD_SET_DISPLAY_OFF, NULL, 0);
- if (ret)
- return ret;
+ power_mode <= MCDE_DISPLAY_PM_STANDBY) {
- ret = mcde_dsi_dcs_write(ddev->chnl_state,
- DCS_CMD_ENTER_SLEEP_MODE, NULL, 0);
+ ret = display_off(ddev);
if (ret)
return ret;
-
ddev->power_mode = MCDE_DISPLAY_PM_STANDBY;
}
- /* SLEEP -> OFF */
+ /* STANDBY -> OFF */
if (ddev->power_mode == MCDE_DISPLAY_PM_STANDBY &&
- power_mode == MCDE_DISPLAY_PM_OFF) {
- if (ddev->platform_disable) {
- ret = ddev->platform_disable(ddev);
- if (ret)
- return ret;
- }
+ power_mode == MCDE_DISPLAY_PM_OFF) {
+ ret = power_off(ddev);
+ if (ret)
+ return ret;
ddev->power_mode = MCDE_DISPLAY_PM_OFF;
}
-set_power_and_exit:
mcde_chnl_set_power_mode(ddev->chnl_state, ddev->power_mode);
- ret = sony_acx424akp_set_scan_mode(ddev, power_mode);
-
- return ret;
+ return sony_acx424akp_set_scan_mode(ddev, power_mode);
}
static int __devinit sony_acx424akp_probe(struct mcde_display_device *dev)
{
int ret = 0;
- u16 id;
+ u16 id = 0;
+ struct device_info *di;
+ struct mcde_port *port;
struct mcde_display_sony_acx424akp_platform_data *pdata =
dev->dev.platform_data;
- if (pdata == NULL) {
- dev_err(&dev->dev, "%s:Platform data missing\n", __func__);
- return -EINVAL;
- }
-
- if (dev->port->type != MCDE_PORTTYPE_DSI) {
- dev_err(&dev->dev,
- "%s:Invalid port type %d\n",
- __func__, dev->port->type);
+ if (pdata == NULL || !pdata->reset_gpio) {
+ dev_err(&dev->dev, "Invalid platform data\n");
return -EINVAL;
}
- if (!dev->platform_enable && !dev->platform_disable) {
- pdata->sony_acx424akp_platform_enable = true;
- if (pdata->reset_gpio) {
- ret = gpio_request(pdata->reset_gpio, NULL);
- if (ret) {
- dev_warn(&dev->dev,
- "%s:Failed to request gpio %d\n",
- __func__, pdata->reset_gpio);
- goto gpio_request_failed;
- }
- gpio_direction_output(pdata->reset_gpio,
- !pdata->reset_high);
- }
- if (pdata->regulator_id) {
- pdata->regulator = regulator_get(NULL,
- pdata->regulator_id);
- if (IS_ERR(pdata->regulator)) {
- ret = PTR_ERR(pdata->regulator);
- dev_warn(&dev->dev,
- "%s:Failed to get regulator '%s'\n",
- __func__, pdata->regulator_id);
- pdata->regulator = NULL;
- goto regulator_get_failed;
- }
- regulator_set_voltage(pdata->regulator,
- pdata->min_supply_voltage,
- pdata->max_supply_voltage);
- /*
- * When u-boot has display a startup screen.
- * U-boot has turned on display power however the
- * regulator framework does not know about that
- * This is the case here, the display driver has to
- * enable the regulator for the display.
- */
- if (dev->power_mode == MCDE_DISPLAY_PM_STANDBY) {
- ret = regulator_enable(pdata->regulator);
- if (ret < 0) {
- dev_err(&dev->dev,
- "%s:Failed to enable regulator\n"
- , __func__);
- goto regulator_enable_failed;
- }
- }
- }
+ di = kzalloc(sizeof(*di), GFP_KERNEL);
+ if (!di)
+ return -ENOMEM;
+
+ port = dev->port;
+ di->reset_gpio = pdata->reset_gpio;
+ di->port.type = MCDE_PORTTYPE_DSI;
+ di->port.mode = MCDE_PORTMODE_CMD;
+ di->port.pixel_format = MCDE_PORTPIXFMT_DSI_24BPP;
+ di->port.sync_src = MCDE_SYNCSRC_BTA;
+ di->port.phy.dsi.num_data_lanes = 2;
+ di->port.link = port->link;
+ /* TODO: Move UI to mcde_hw.c when clk_get_rate(dsi) is done */
+ di->port.phy.dsi.ui = 9;
+
+ ret = gpio_request(di->reset_gpio, NULL);
+ if (WARN_ON(ret))
+ goto gpio_request_failed;
+
+ gpio_direction_output(di->reset_gpio, 1);
+ di->regulator = regulator_get(&dev->dev, IO_REGU);
+ if (IS_ERR(di->regulator)) {
+ ret = PTR_ERR(di->regulator);
+ di->regulator = NULL;
+ goto regulator_get_failed;
}
+ ret = regulator_set_voltage(di->regulator, IO_REGU_MIN, IO_REGU_MAX);
+ if (WARN_ON(ret))
+ goto regulator_voltage_failed;
- /* TODO: Remove when DSI send command uses interrupts */
- dev->platform_enable = sony_acx424akp_platform_enable,
- dev->platform_disable = sony_acx424akp_platform_disable,
dev->set_power_mode = sony_acx424akp_set_power_mode;
+ dev->port = &di->port;
+ dev->native_x_res = 480;
+ dev->native_y_res = 854;
+ dev_set_drvdata(&dev->dev, di);
+
+ /*
+ * When u-boot has display a startup screen.
+ * U-boot has turned on display power however the
+ * regulator framework does not know about that
+ * This is the case here, the display driver has to
+ * enable the regulator for the display.
+ */
+ if (dev->power_mode == MCDE_DISPLAY_PM_STANDBY) {
+ (void) regulator_enable(di->regulator);
+ } else if (dev->power_mode == MCDE_DISPLAY_PM_OFF) {
+ power_on(dev);
+ dev->power_mode = MCDE_DISPLAY_PM_STANDBY;
+ }
+
ret = display_read_deviceid(dev, &id);
+ if (ret)
+ goto read_id_failed;
switch (id) {
case DISPLAY_SONY_ACX424AKP:
pdata->disp_panel = DISPLAY_SONY_ACX424AKP;
- dev_info(&dev->dev, "Sony ACX424AKP display (ID 0x%.4X) \
- probed\n", id);
- goto out;
-
+ dev_info(&dev->dev,
+ "Sony ACX424AKP display (ID 0x%.4X) probed\n", id);
+ break;
default:
pdata->disp_panel = DISPLAY_NONE;
- dev_warn(&dev->dev, "Display not recognized\n");
- break;
+ dev_info(&dev->dev,
+ "Display not recognized (ID 0x%.4X) probed\n", id);
+ goto read_id_failed;
}
-regulator_enable_failed:
+ return 0;
+
+read_id_failed:
+regulator_voltage_failed:
+ regulator_put(di->regulator);
regulator_get_failed:
- if (pdata->sony_acx424akp_platform_enable && pdata->reset_gpio)
- gpio_free(pdata->reset_gpio);
+ gpio_free(di->reset_gpio);
gpio_request_failed:
-out:
+ kfree(di);
return ret;
}
static int __devexit sony_acx424akp_remove(struct mcde_display_device *dev)
{
- struct mcde_display_sony_acx424akp_platform_data *pdata =
- dev->dev.platform_data;
+ struct device_info *di = get_drvdata(dev);
dev->set_power_mode(dev, MCDE_DISPLAY_PM_OFF);
- if (!pdata->sony_acx424akp_platform_enable)
- return 0;
+ regulator_put(di->regulator);
+ gpio_direction_input(di->reset_gpio);
+ gpio_free(di->reset_gpio);
- if (pdata->regulator)
- regulator_put(pdata->regulator);
- if (pdata->reset_gpio) {
- gpio_direction_input(pdata->reset_gpio);
- gpio_free(pdata->reset_gpio);
- }
+ kfree(di);
return 0;
}
diff --git a/include/video/mcde_display-sony_acx424akp_dsi.h b/include/video/mcde_display-sony_acx424akp_dsi.h
index de862a3f28b..c00c3513da3 100644
--- a/include/video/mcde_display-sony_acx424akp_dsi.h
+++ b/include/video/mcde_display-sony_acx424akp_dsi.h
@@ -31,8 +31,6 @@ struct mcde_display_sony_acx424akp_platform_data {
enum display_panel_type disp_panel; /* display panel types */
/* Driver data */
- bool sony_acx424akp_platform_enable;
- struct regulator *regulator;
int max_supply_voltage;
int min_supply_voltage;
};