panel
This commit is contained in:
@@ -345,81 +345,83 @@ static inline struct nx_panel *to_nx_panel(struct drm_panel *panel)
|
||||
return container_of(panel, struct nx_panel, base);
|
||||
}
|
||||
|
||||
static void nx_panel_detect(struct nx_panel *jdi)
|
||||
static void nx_panel_detect(struct nx_panel *nx)
|
||||
{
|
||||
int ret;
|
||||
jdi->init_cmds = NULL;
|
||||
jdi->suspend_cmds = NULL;
|
||||
nx->init_cmds = NULL;
|
||||
nx->suspend_cmds = NULL;
|
||||
|
||||
memset(jdi->display_id, 0, sizeof(jdi->display_id));
|
||||
printk("nx_panel_detect");
|
||||
|
||||
ret = mipi_dsi_dcs_read(jdi->dsi, MIPI_DCS_GET_DISPLAY_ID,
|
||||
jdi->display_id, sizeof(jdi->display_id));
|
||||
memset(nx->display_id, 0, sizeof(nx->display_id));
|
||||
|
||||
ret = mipi_dsi_dcs_read(nx->dsi, MIPI_DCS_GET_DISPLAY_ID,
|
||||
nx->display_id, sizeof(nx->display_id));
|
||||
if (ret < 0) {
|
||||
dev_err(&jdi->dsi->dev, "failed to read panel ID: %d\n", ret);
|
||||
dev_err(&nx->dsi->dev, "failed to read panel ID: %d\n", ret);
|
||||
} else {
|
||||
dev_info(&jdi->dsi->dev, "display ID[%d]: %02x %02x %02x\n",
|
||||
ret, jdi->display_id[0], jdi->display_id[1],
|
||||
jdi->display_id[2]);
|
||||
dev_info(&nx->dsi->dev, "display ID[%d]: %02x %02x %02x\n",
|
||||
ret, nx->display_id[0], nx->display_id[1],
|
||||
nx->display_id[2]);
|
||||
}
|
||||
|
||||
dev_info(&jdi->dsi->dev,
|
||||
"setting init sequence for ID %02x\n", jdi->display_id[0]);
|
||||
dev_info(&nx->dsi->dev,
|
||||
"setting init sequence for ID %02x\n", nx->display_id[0]);
|
||||
|
||||
switch (jdi->display_id[0]) {
|
||||
switch (nx->display_id[0]) {
|
||||
case PANEL_JDI_XXX062M:
|
||||
jdi->init_cmds = init_cmds_PANEL_JDI_XXX062M;
|
||||
nx->init_cmds = init_cmds_PANEL_JDI_XXX062M;
|
||||
break;
|
||||
case PANEL_SAM_AMS699VC01:
|
||||
jdi->init_cmds = init_cmds_PANEL_SAM_AMS699VC01;
|
||||
nx->init_cmds = init_cmds_PANEL_SAM_AMS699VC01;
|
||||
break;
|
||||
case PANEL_INL_P062CCA_AZ1:
|
||||
jdi->init_cmds = init_cmds_PANEL_INL_P062CCA_AZ1;
|
||||
nx->init_cmds = init_cmds_PANEL_INL_P062CCA_AZ1;
|
||||
break;
|
||||
case PANEL_AUO_A062TAN01:
|
||||
jdi->init_cmds = init_cmds_PANEL_AUO_A062TAN01;
|
||||
nx->init_cmds = init_cmds_PANEL_AUO_A062TAN01;
|
||||
break;
|
||||
case PANEL_INL_2J055IA_27A:
|
||||
case PANEL_AUO_A055TAN01:
|
||||
case PANEL_SHP_LQ055T1SW10:
|
||||
default:
|
||||
dev_info(&jdi->dsi->dev, "using default init sequence\n");
|
||||
jdi->init_cmds = init_cmds_default;
|
||||
dev_info(&nx->dsi->dev, "using default init sequence\n");
|
||||
nx->init_cmds = init_cmds_default;
|
||||
break;
|
||||
}
|
||||
|
||||
dev_info(&jdi->dsi->dev,
|
||||
"setting suspend sequence for ID %02x\n", jdi->display_id[0]);
|
||||
dev_info(&nx->dsi->dev,
|
||||
"setting suspend sequence for ID %02x\n", nx->display_id[0]);
|
||||
|
||||
switch (jdi->display_id[0]) {
|
||||
switch (nx->display_id[0]) {
|
||||
case PANEL_JDI_XXX062M:
|
||||
jdi->suspend_cmds = suspend_cmds_PANEL_JDI_XXX062M;
|
||||
nx->suspend_cmds = suspend_cmds_PANEL_JDI_XXX062M;
|
||||
break;
|
||||
case PANEL_AUO_A062TAN01:
|
||||
jdi->suspend_cmds = suspend_cmds_PANEL_AUO_A062TAN01;
|
||||
nx->suspend_cmds = suspend_cmds_PANEL_AUO_A062TAN01;
|
||||
break;
|
||||
case PANEL_INL_2J055IA_27A:
|
||||
jdi->suspend_cmds = suspend_cmds_PANEL_INL_2J055IA_27A;
|
||||
nx->suspend_cmds = suspend_cmds_PANEL_INL_2J055IA_27A;
|
||||
break;
|
||||
case PANEL_AUO_A055TAN01:
|
||||
jdi->suspend_cmds = suspend_cmds_PANEL_AUO_A055TAN01;
|
||||
nx->suspend_cmds = suspend_cmds_PANEL_AUO_A055TAN01;
|
||||
break;
|
||||
case PANEL_SHP_LQ055T1SW10:
|
||||
jdi->suspend_cmds = suspend_cmds_PANEL_SHP_LQ055T1SW10;
|
||||
nx->suspend_cmds = suspend_cmds_PANEL_SHP_LQ055T1SW10;
|
||||
break;
|
||||
case PANEL_SAM_AMS699VC01:
|
||||
jdi->suspend_cmds = suspend_cmds_PANEL_SAM_AMS699VC01;
|
||||
nx->suspend_cmds = suspend_cmds_PANEL_SAM_AMS699VC01;
|
||||
break;
|
||||
case PANEL_INL_P062CCA_AZ1:
|
||||
default:
|
||||
dev_info(&jdi->dsi->dev, "using default suspend sequence\n");
|
||||
dev_info(&nx->dsi->dev, "using default suspend sequence\n");
|
||||
break;
|
||||
}
|
||||
|
||||
msleep(20);
|
||||
}
|
||||
|
||||
static int jdi_mipi_dsi_dcs_cmds(struct init_cmd *cmds, struct nx_panel *jdi)
|
||||
static int nx_mipi_dsi_dcs_cmds(struct init_cmd *cmds, struct nx_panel *nx)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
@@ -427,10 +429,10 @@ static int jdi_mipi_dsi_dcs_cmds(struct init_cmd *cmds, struct nx_panel *jdi)
|
||||
if (cmds->cmd == 0xFF)
|
||||
msleep(cmds->length);
|
||||
else {
|
||||
ret = mipi_dsi_dcs_write(jdi->dsi, cmds->cmd,
|
||||
ret = mipi_dsi_dcs_write(nx->dsi, cmds->cmd,
|
||||
cmds->data, cmds->length);
|
||||
if (ret < 0) {
|
||||
dev_err(&jdi->dsi->dev,
|
||||
dev_err(&nx->dsi->dev,
|
||||
"failed to write dsi_cmd: %d error: %d\n",
|
||||
cmds->cmd, ret);
|
||||
return ret;
|
||||
@@ -442,14 +444,16 @@ static int jdi_mipi_dsi_dcs_cmds(struct init_cmd *cmds, struct nx_panel *jdi)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int nx_panel_init(struct nx_panel *jdi)
|
||||
static int nx_panel_init(struct nx_panel *nx)
|
||||
{
|
||||
struct mipi_dsi_device *dsi = jdi->dsi;
|
||||
struct device *dev = &jdi->dsi->dev;
|
||||
struct mipi_dsi_device *dsi = nx->dsi;
|
||||
struct device *dev = &nx->dsi->dev;
|
||||
int ret;
|
||||
|
||||
dsi->mode_flags |= MIPI_DSI_MODE_LPM;
|
||||
|
||||
printk("nx_panel_init");
|
||||
|
||||
ret = mipi_dsi_set_maximum_return_packet_size(dsi, 3);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to set maximum return packet size: %d\n",
|
||||
@@ -457,19 +461,19 @@ static int nx_panel_init(struct nx_panel *jdi)
|
||||
return ret;
|
||||
}
|
||||
|
||||
nx_panel_detect(jdi);
|
||||
nx_panel_detect(nx);
|
||||
|
||||
ret = jdi_mipi_dsi_dcs_cmds(jdi->init_cmds, jdi);
|
||||
ret = nx_mipi_dsi_dcs_cmds(nx->init_cmds, nx);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = mipi_dsi_dcs_set_column_address(dsi, 0, jdi->mode->hdisplay - 1);
|
||||
ret = mipi_dsi_dcs_set_column_address(dsi, 0, nx->mode->hdisplay - 1);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to set page address: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mipi_dsi_dcs_set_page_address(dsi, 0, jdi->mode->vdisplay - 1);
|
||||
ret = mipi_dsi_dcs_set_page_address(dsi, 0, nx->mode->vdisplay - 1);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to set column address: %d\n", ret);
|
||||
return ret;
|
||||
@@ -492,104 +496,106 @@ static int nx_panel_init(struct nx_panel *jdi)
|
||||
|
||||
static int nx_panel_enable(struct drm_panel *panel)
|
||||
{
|
||||
struct nx_panel *jdi = to_nx_panel(panel);
|
||||
struct nx_panel *nx = to_nx_panel(panel);
|
||||
|
||||
if (jdi->enabled)
|
||||
if (nx->enabled)
|
||||
return 0;
|
||||
|
||||
backlight_enable(jdi->backlight);
|
||||
backlight_enable(nx->backlight);
|
||||
|
||||
jdi->enabled = true;
|
||||
nx->enabled = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nx_panel_disable(struct drm_panel *panel)
|
||||
{
|
||||
struct nx_panel *jdi = to_nx_panel(panel);
|
||||
struct nx_panel *nx = to_nx_panel(panel);
|
||||
|
||||
if (!jdi->enabled)
|
||||
if (!nx->enabled)
|
||||
return 0;
|
||||
|
||||
backlight_disable(jdi->backlight);
|
||||
backlight_disable(nx->backlight);
|
||||
|
||||
jdi->enabled = false;
|
||||
nx->enabled = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nx_panel_unprepare(struct drm_panel *panel)
|
||||
{
|
||||
struct nx_panel *jdi = to_nx_panel(panel);
|
||||
struct nx_panel *nx = to_nx_panel(panel);
|
||||
int ret;
|
||||
|
||||
if (!jdi->prepared)
|
||||
if (!nx->prepared)
|
||||
return 0;
|
||||
|
||||
jdi->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
|
||||
nx->dsi->mode_flags &= ~MIPI_DSI_MODE_LPM;
|
||||
|
||||
ret = jdi_mipi_dsi_dcs_cmds(jdi->suspend_cmds, jdi);
|
||||
ret = nx_mipi_dsi_dcs_cmds(nx->suspend_cmds, nx);
|
||||
if (ret < 0)
|
||||
dev_err(&jdi->dsi->dev, "failed to write suspend cmds: %d\n",
|
||||
dev_err(&nx->dsi->dev, "failed to write suspend cmds: %d\n",
|
||||
ret);
|
||||
|
||||
if (jdi->reset_gpio)
|
||||
gpiod_set_value(jdi->reset_gpio, 0);
|
||||
if (nx->reset_gpio)
|
||||
gpiod_set_value(nx->reset_gpio, 0);
|
||||
|
||||
msleep(10);
|
||||
regulator_disable(jdi->supply2);
|
||||
regulator_disable(nx->supply2);
|
||||
msleep(10);
|
||||
regulator_disable(jdi->supply1);
|
||||
regulator_disable(nx->supply1);
|
||||
|
||||
jdi->prepared = false;
|
||||
nx->prepared = false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nx_panel_prepare(struct drm_panel *panel)
|
||||
{
|
||||
struct nx_panel *jdi = to_nx_panel(panel);
|
||||
struct device *dev = &jdi->dsi->dev;
|
||||
struct nx_panel *nx = to_nx_panel(panel);
|
||||
struct device *dev = &nx->dsi->dev;
|
||||
int ret;
|
||||
|
||||
if (jdi->prepared)
|
||||
printk("nx panel prepare");
|
||||
|
||||
if (nx->prepared)
|
||||
return 0;
|
||||
|
||||
ret = regulator_enable(jdi->supply1);
|
||||
ret = regulator_enable(nx->supply1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
msleep(10);
|
||||
|
||||
ret = regulator_enable(jdi->supply2);
|
||||
ret = regulator_enable(nx->supply2);
|
||||
if (ret < 0)
|
||||
goto poweroff;
|
||||
msleep(10);
|
||||
|
||||
if (jdi->reset_gpio) {
|
||||
gpiod_set_value(jdi->reset_gpio, 0);
|
||||
if (nx->reset_gpio) {
|
||||
gpiod_set_value(nx->reset_gpio, 0);
|
||||
msleep(10);
|
||||
gpiod_set_value(jdi->reset_gpio, 1);
|
||||
gpiod_set_value(nx->reset_gpio, 1);
|
||||
msleep(60);
|
||||
}
|
||||
jdi->dsi->mode_flags |= MIPI_DSI_MODE_LPM;
|
||||
nx->dsi->mode_flags |= MIPI_DSI_MODE_LPM;
|
||||
|
||||
ret = nx_panel_init(jdi);
|
||||
ret = nx_panel_init(nx);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "failed to init panel: %d\n", ret);
|
||||
goto reset;
|
||||
}
|
||||
|
||||
jdi->prepared = true;
|
||||
nx->prepared = true;
|
||||
|
||||
return 0;
|
||||
|
||||
reset:
|
||||
if (jdi->reset_gpio)
|
||||
gpiod_set_value(jdi->reset_gpio, 0);
|
||||
regulator_disable(jdi->supply2);
|
||||
if (nx->reset_gpio)
|
||||
gpiod_set_value(nx->reset_gpio, 0);
|
||||
regulator_disable(nx->supply2);
|
||||
|
||||
poweroff:
|
||||
regulator_disable(jdi->supply1);
|
||||
regulator_disable(nx->supply1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -611,8 +617,10 @@ static int nx_panel_get_modes(struct drm_panel *panel,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct drm_display_mode *mode;
|
||||
struct nx_panel *jdi = to_nx_panel(panel);
|
||||
struct device *dev = &jdi->dsi->dev;
|
||||
struct nx_panel *nx = to_nx_panel(panel);
|
||||
struct device *dev = &nx->dsi->dev;
|
||||
|
||||
printk("nx panel get_modes");
|
||||
|
||||
mode = drm_mode_duplicate(connector->dev, &default_mode);
|
||||
if (!mode) {
|
||||
@@ -639,59 +647,67 @@ static const struct drm_panel_funcs nx_panel_funcs = {
|
||||
.get_modes = nx_panel_get_modes,
|
||||
};
|
||||
|
||||
static int nx_panel_add(struct nx_panel *jdi)
|
||||
static int nx_panel_add(struct nx_panel *nx)
|
||||
{
|
||||
struct device *dev = &jdi->dsi->dev;
|
||||
struct device *dev = &nx->dsi->dev;
|
||||
struct device_node *np;
|
||||
|
||||
jdi->mode = &default_mode;
|
||||
printk("nx_panel_add");
|
||||
|
||||
jdi->supply1 = devm_regulator_get(dev, "vdd1");
|
||||
if (IS_ERR(jdi->supply1))
|
||||
return PTR_ERR(jdi->supply1);
|
||||
nx->mode = &default_mode;
|
||||
|
||||
jdi->supply2 = devm_regulator_get(dev, "vdd2");
|
||||
if (IS_ERR(jdi->supply2))
|
||||
return PTR_ERR(jdi->supply2);
|
||||
nx->supply1 = devm_regulator_get(dev, "vdd1");
|
||||
if (IS_ERR(nx->supply1))
|
||||
return PTR_ERR(nx->supply1);
|
||||
|
||||
jdi->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(jdi->reset_gpio)) {
|
||||
nx->supply2 = devm_regulator_get(dev, "vdd2");
|
||||
if (IS_ERR(nx->supply2))
|
||||
return PTR_ERR(nx->supply2);
|
||||
|
||||
nx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
|
||||
if (IS_ERR(nx->reset_gpio)) {
|
||||
dev_err(dev, "cannot get reset-gpios %ld\n",
|
||||
PTR_ERR(jdi->reset_gpio));
|
||||
jdi->reset_gpio = NULL;
|
||||
PTR_ERR(nx->reset_gpio));
|
||||
nx->reset_gpio = NULL;
|
||||
} else {
|
||||
gpiod_set_value(jdi->reset_gpio, 0);
|
||||
gpiod_set_value(nx->reset_gpio, 0);
|
||||
}
|
||||
|
||||
printk("backlight");
|
||||
|
||||
np = of_parse_phandle(dev->of_node, "backlight", 0);
|
||||
if (np) {
|
||||
jdi->backlight = of_find_backlight_by_node(np);
|
||||
nx->backlight = of_find_backlight_by_node(np);
|
||||
of_node_put(np);
|
||||
|
||||
if (!jdi->backlight)
|
||||
if (!nx->backlight)
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
|
||||
drm_panel_init(&jdi->base, &jdi->dsi->dev, &nx_panel_funcs,
|
||||
printk("panel init");
|
||||
|
||||
drm_panel_init(&nx->base, &nx->dsi->dev, &nx_panel_funcs,
|
||||
DRM_MODE_CONNECTOR_DSI);
|
||||
|
||||
drm_panel_add(&jdi->base);
|
||||
printk("drm panel add");
|
||||
|
||||
drm_panel_add(&nx->base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nx_panel_del(struct nx_panel *jdi)
|
||||
static void nx_panel_del(struct nx_panel *nx)
|
||||
{
|
||||
if (jdi->base.dev)
|
||||
drm_panel_remove(&jdi->base);
|
||||
if (nx->base.dev)
|
||||
drm_panel_remove(&nx->base);
|
||||
|
||||
if (jdi->backlight)
|
||||
put_device(&jdi->backlight->dev);
|
||||
if (nx->backlight)
|
||||
put_device(&nx->backlight->dev);
|
||||
}
|
||||
|
||||
static int nx_panel_probe(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
struct nx_panel *jdi;
|
||||
struct nx_panel *nx;
|
||||
int ret;
|
||||
|
||||
dsi->lanes = 4;
|
||||
@@ -700,21 +716,28 @@ static int nx_panel_probe(struct mipi_dsi_device *dsi)
|
||||
MIPI_DSI_CLOCK_NON_CONTINUOUS |
|
||||
MIPI_DSI_MODE_NO_EOT_PACKET;
|
||||
|
||||
jdi = devm_kzalloc(&dsi->dev, sizeof(*jdi), GFP_KERNEL);
|
||||
if (!jdi)
|
||||
printk("nx_panel_probe");
|
||||
|
||||
nx = devm_kzalloc(&dsi->dev, sizeof(*nx), GFP_KERNEL);
|
||||
if (!nx)
|
||||
return -ENOMEM;
|
||||
|
||||
mipi_dsi_set_drvdata(dsi, jdi);
|
||||
printk("set drvdata");
|
||||
|
||||
jdi->dsi = dsi;
|
||||
mipi_dsi_set_drvdata(dsi, nx);
|
||||
|
||||
ret = nx_panel_add(jdi);
|
||||
nx->dsi = dsi;
|
||||
|
||||
printk("add panel");
|
||||
|
||||
ret = nx_panel_add(nx);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
printk("dsi attach");
|
||||
ret = mipi_dsi_attach(dsi);
|
||||
if (ret < 0) {
|
||||
nx_panel_del(jdi);
|
||||
nx_panel_del(nx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -723,10 +746,12 @@ static int nx_panel_probe(struct mipi_dsi_device *dsi)
|
||||
|
||||
static void nx_panel_remove(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
struct nx_panel *jdi = mipi_dsi_get_drvdata(dsi);
|
||||
struct nx_panel *nx = mipi_dsi_get_drvdata(dsi);
|
||||
int ret;
|
||||
|
||||
ret = nx_panel_disable(&jdi->base);
|
||||
printk("nx_panel_remove");
|
||||
|
||||
ret = nx_panel_disable(&nx->base);
|
||||
if (ret < 0)
|
||||
dev_err(&dsi->dev, "failed to disable panel: %d\n", ret);
|
||||
|
||||
@@ -734,27 +759,27 @@ static void nx_panel_remove(struct mipi_dsi_device *dsi)
|
||||
if (ret < 0)
|
||||
dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", ret);
|
||||
|
||||
nx_panel_del(jdi);
|
||||
nx_panel_del(nx);
|
||||
}
|
||||
|
||||
static void nx_panel_shutdown(struct mipi_dsi_device *dsi)
|
||||
{
|
||||
struct nx_panel *jdi = mipi_dsi_get_drvdata(dsi);
|
||||
nx_panel_disable(&jdi->base);
|
||||
struct nx_panel *nx = mipi_dsi_get_drvdata(dsi);
|
||||
nx_panel_disable(&nx->base);
|
||||
}
|
||||
|
||||
static const struct of_device_id jdi_of_match[] = {
|
||||
static const struct of_device_id nx_panel_of_match[] = {
|
||||
{
|
||||
.compatible = "nintendo,panel-nx-dsi",
|
||||
.compatible = "nintendo,nx-dsi",
|
||||
},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, jdi_of_match);
|
||||
MODULE_DEVICE_TABLE(of, nx_panel_of_match);
|
||||
|
||||
static struct mipi_dsi_driver nx_panel_driver = {
|
||||
.driver = {
|
||||
.name = "panel-nx-dsi",
|
||||
.of_match_table = jdi_of_match,
|
||||
.of_match_table = nx_panel_of_match,
|
||||
},
|
||||
.probe = nx_panel_probe,
|
||||
.remove = nx_panel_remove,
|
||||
|
||||
Reference in New Issue
Block a user