From 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Mon, 13 May 2024 10:30:14 +0000
Subject: [PATCH] modify sin led gpio
---
kernel/drivers/mfd/rkx110_x120/rkx110_x120_core.c | 474 ++++++++++++++++++++++++++++------------------------------
1 files changed, 229 insertions(+), 245 deletions(-)
diff --git a/kernel/drivers/mfd/rkx110_x120/rkx110_x120_core.c b/kernel/drivers/mfd/rkx110_x120/rkx110_x120_core.c
index 95d875b..ee9e962 100644
--- a/kernel/drivers/mfd/rkx110_x120/rkx110_x120_core.c
+++ b/kernel/drivers/mfd/rkx110_x120/rkx110_x120_core.c
@@ -10,9 +10,12 @@
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
+#include <linux/irq.h>
#include <linux/gpio/consumer.h>
+#include <linux/regulator/consumer.h>
#include <linux/mfd/core.h>
#include "rkx110_x120.h"
+#include "rkx110_x120_display.h"
#include "rkx110_reg.h"
#include "rkx110_dsi_rx.h"
#include "rkx120_dsi_tx.h"
@@ -22,8 +25,44 @@
static const struct mfd_cell rkx110_x120_devs[] = {
/* 2 panel device for rkx110_x120 drm panel */
{
- .name = "serdes-panel",
+ .name = "rockchip-serdes-panel",
.of_compatible = "rockchip,serdes-panel",
+ },
+ {
+ .name = "rockchip-serdes-panel1",
+ .of_compatible = "rockchip,serdes-panel",
+ },
+ {
+ .name = "rkx120-pwm0",
+ .of_compatible = "rockchip,rkx120-pwm",
+ },
+ {
+ .name = "rkx120-pwm1",
+ .of_compatible = "rockchip,rkx120-pwm",
+ },
+ {
+ .name = "rkx120-pwm2",
+ .of_compatible = "rockchip,rkx120-pwm",
+ },
+ {
+ .name = "rkx120-pwm3",
+ .of_compatible = "rockchip,rkx120-pwm",
+ },
+ {
+ .name = "rkx120-pwm4",
+ .of_compatible = "rockchip,rkx120-pwm",
+ },
+ {
+ .name = "rkx120-pwm5",
+ .of_compatible = "rockchip,rkx120-pwm",
+ },
+ {
+ .name = "rkx120-pwm6",
+ .of_compatible = "rockchip,rkx120-pwm",
+ },
+ {
+ .name = "rkx120-pwm7",
+ .of_compatible = "rockchip,rkx120-pwm",
},
};
@@ -111,26 +150,40 @@
return serdes->rkx110_debug || serdes->rkx120_debug;
}
-static void rk_serdes_wait_link_ready(struct rk_serdes *serdes)
+static int rk_serdes_wait_link_ready(struct rk_serdes *serdes)
{
+ int ret;
+
if (serdes->stream_type == STREAM_DISPLAY) {
- rkx110_linktx_wait_link_ready(serdes, 0);
- if (serdes->route_flag & ROUTE_MULTI_LANE) {
+ ret = rkx110_linktx_wait_link_ready(serdes, 0);
+ if (ret)
+ return ret;
+
+ if (serdes->lane_nr == 2) {
rkx110_ser_pma_enable(serdes, true, 1, DEVICE_LOCAL);
- if (!(serdes->route_flag & ROUTE_MULTI_REMOTE))
+ if (!(serdes->remote_nr == 2))
rkx120_des_pma_enable(serdes, true, 1, DEVICE_REMOTE0);
- rkx110_linktx_wait_link_ready(serdes, 1);
+ ret = rkx110_linktx_wait_link_ready(serdes, 1);
+ if (ret)
+ return ret;
}
} else {
- rkx120_linkrx_wait_link_ready(serdes, 0);
- if (serdes->route_flag & ROUTE_MULTI_LANE) {
+ ret = rkx120_linkrx_wait_link_ready(serdes, 0);
+ if (ret)
+ return ret;
+
+ if (serdes->lane_nr == 2) {
rkx120_des_pma_enable(serdes, true, 1, DEVICE_LOCAL);
- if (!(serdes->route_flag & ROUTE_MULTI_REMOTE))
+ if (!(serdes->remote_nr == 2))
rkx110_ser_pma_enable(serdes, true, 1, DEVICE_REMOTE0);
- rkx120_linkrx_wait_link_ready(serdes, 1);
+ ret = rkx120_linkrx_wait_link_ready(serdes, 1);
+ if (ret)
+ return ret;
}
}
+
+ return 0;
}
static void rk_serdes_print_rate(struct rk_serdes *serdes, enum rk_serdes_rate rate)
@@ -302,9 +355,9 @@
if (serdes->stream_type == STREAM_DISPLAY) {
rkx110_pma_set_rate(serdes, &rkx110_pll, 0, DEVICE_LOCAL);
rkx120_pma_set_rate(serdes, &rkx120_pll, 0, DEVICE_REMOTE0);
- if (serdes->route_flag & ROUTE_MULTI_LANE) {
+ if (serdes->lane_nr == 2) {
rkx110_pma_set_rate(serdes, &rkx110_pll, 1, DEVICE_LOCAL);
- if (serdes->route_flag & ROUTE_MULTI_REMOTE)
+ if (serdes->remote_nr == 2)
rkx120_pma_set_rate(serdes, &rkx120_pll, 0, DEVICE_REMOTE1);
else
rkx120_pma_set_rate(serdes, &rkx120_pll, 1, DEVICE_REMOTE0);
@@ -315,9 +368,9 @@
} else {
rkx120_pma_set_rate(serdes, &rkx120_pll, 0, DEVICE_LOCAL);
rkx110_pma_set_rate(serdes, &rkx110_pll, 0, DEVICE_REMOTE0);
- if (serdes->route_flag & ROUTE_MULTI_LANE) {
+ if (serdes->lane_nr == 2) {
rkx120_pma_set_rate(serdes, &rkx120_pll, 1, DEVICE_LOCAL);
- if (serdes->route_flag & ROUTE_MULTI_REMOTE)
+ if (serdes->remote_nr == 2)
rkx110_pma_set_rate(serdes, &rkx110_pll, 0, DEVICE_REMOTE1);
else
rkx110_pma_set_rate(serdes, &rkx110_pll, 1, DEVICE_REMOTE0);
@@ -330,225 +383,6 @@
rk_serdes_wait_link_ready(serdes);
serdes->rate = rate;
-}
-
-static int rk_serdes_route_prepare(struct rk_serdes *serdes, struct rk_serdes_route *route)
-{
- if (rk_serdes_debug_mode(serdes))
- return 0;
-
- if (route->stream_type == STREAM_DISPLAY) {
- switch (route->local_port0) {
- case RK_SERDES_RGB_RX:
- rkx110_rgb_rx_enable(serdes, route);
- break;
- case RK_SERDES_LVDS_RX0:
- rkx110_lvds_rx_enable(serdes, route, 0);
- if (serdes->route_flag & ROUTE_MULTI_LVDS_INPUT)
- rkx110_lvds_rx_enable(serdes, route, 1);
- break;
- case RK_SERDES_LVDS_RX1:
- rkx110_lvds_rx_enable(serdes, route, 1);
- if (serdes->route_flag & ROUTE_MULTI_LVDS_INPUT)
- rkx110_lvds_rx_enable(serdes, route, 0);
- break;
- case RK_SERDES_DUAL_LVDS_RX:
- rkx110_lvds_rx_enable(serdes, route, 0);
- rkx110_lvds_rx_enable(serdes, route, 1);
- break;
- case RK_SERDES_DSI_RX0:
- rkx110_dsi_rx_enable(serdes, route, 0);
- if (serdes->route_flag & ROUTE_MULTI_DSI_INPUT)
- rkx110_dsi_rx_enable(serdes, route, 1);
- break;
- case RK_SERDES_DSI_RX1:
- rkx110_dsi_rx_enable(serdes, route, 1);
- if (serdes->route_flag & ROUTE_MULTI_DSI_INPUT)
- rkx110_dsi_rx_enable(serdes, route, 0);
- break;
- default:
- dev_info(serdes->dev, "undefined local port0");
- return -EINVAL;
- }
-
- rkx110_linktx_enable(serdes, route);
-
- rkx120_linkrx_enable(serdes, route, DEVICE_REMOTE0);
- if (serdes->route_flag & ROUTE_MULTI_REMOTE)
- rkx120_linkrx_enable(serdes, route, DEVICE_REMOTE1);
-
- if (route->remote0_port0 & RK_SERDES_DSI_TX0)
- rkx120_dsi_tx_pre_enable(serdes, route, DEVICE_REMOTE0);
- if (route->remote1_port0 & RK_SERDES_DSI_TX0)
- rkx120_dsi_tx_pre_enable(serdes, route, DEVICE_REMOTE1);
- } else {
- /* for camera stream */
- }
-
- return 0;
-}
-
-static int rk_serdes_route_enable(struct rk_serdes *serdes, struct rk_serdes_route *route)
-{
- if (rk_serdes_debug_mode(serdes))
- return 0;
-
- if (route->stream_type == STREAM_DISPLAY) {
- switch (route->remote0_port0) {
- case RK_SERDES_RGB_TX:
- rkx120_rgb_tx_enable(serdes, route, DEVICE_REMOTE0);
- break;
- case RK_SERDES_LVDS_TX0:
- rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE0, 0);
- break;
- case RK_SERDES_LVDS_TX1:
- rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE0, 1);
- break;
- case RK_SERDES_DUAL_LVDS_TX:
- rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE0, 0);
- rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE0, 1);
- break;
- case RK_SERDES_DSI_TX0:
- rkx120_dsi_tx_enable(serdes, route, DEVICE_REMOTE0);
- break;
- default:
- dev_err(serdes->dev, "undefined remote0_port0\n");
- return -EINVAL;
- }
-
- if (serdes->route_flag & ROUTE_MULTI_REMOTE) {
- switch (route->remote1_port0) {
- case RK_SERDES_RGB_TX:
- rkx120_rgb_tx_enable(serdes, route, DEVICE_REMOTE1);
- break;
- case RK_SERDES_LVDS_TX0:
- rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE1, 0);
- break;
- case RK_SERDES_LVDS_TX1:
- rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE1, 1);
- break;
- case RK_SERDES_DUAL_LVDS_TX:
- rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE1, 0);
- rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE1, 1);
- break;
- case RK_SERDES_DSI_TX0:
- rkx120_dsi_tx_enable(serdes, route, DEVICE_REMOTE1);
- break;
- default:
- dev_err(serdes->dev, "undefined remote1_port0\n");
- return -EINVAL;
- }
- } else if (serdes->route_flag & ROUTE_MULTI_CHANNEL) {
- if (route->remote0_port1 & RK_SERDES_LVDS_TX0) {
- rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE0, 0);
- } else if (route->remote0_port1 & RK_SERDES_LVDS_TX1) {
- rkx120_lvds_tx_enable(serdes, route, DEVICE_REMOTE0, 1);
- } else {
- dev_err(serdes->dev, "undefined remote0_port1\n");
- return -EINVAL;
- }
- }
-
- if (serdes->version == SERDES_V1) {
- rkx120_linkrx_engine_enable(serdes, 0, DEVICE_REMOTE0, true);
- rkx110_linktx_channel_enable(serdes, 0, DEVICE_LOCAL, true);
- }
-
- rkx110_linktx_video_enable(serdes, DEVICE_LOCAL, true);
- } else {
- /* for camera stream */
- }
-
- return 0;
-}
-
-static int rk_serdes_route_disable(struct rk_serdes *serdes, struct rk_serdes_route *route)
-{
- if (route->stream_type == STREAM_DISPLAY) {
- if (route->remote0_port0 & RK_SERDES_DSI_TX0)
- rkx120_dsi_tx_disable(serdes, route, DEVICE_REMOTE0);
-
- if (serdes->version == SERDES_V1) {
- rkx120_linkrx_engine_enable(serdes, 0, DEVICE_REMOTE0, false);
- rkx110_linktx_channel_enable(serdes, 0, DEVICE_LOCAL, false);
-
- if (route->local_port0 == RK_SERDES_DUAL_LVDS_RX) {
- rkx110_set_stream_source(serdes, RK_SERDES_RGB_RX,
- DEVICE_LOCAL);
- hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk,
- RKX110_SRST_RESETN_2X_LVDS_RKLINK_TX);
- hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk,
- RKX110_SRST_RESETN_D_LVDS0_RKLINK_TX);
- hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk,
- RKX110_SRST_RESETN_D_LVDS1_RKLINK_TX);
- }
-
- if ((route->local_port0 == RK_SERDES_DSI_RX0) ||
- (route->local_port1 == RK_SERDES_DSI_RX0)) {
- serdes->i2c_write_reg(serdes->chip[DEVICE_LOCAL].client, 0x0314,
- 0x1400140);
- hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk,
- RKX111_SRST_RESETN_D_DSI_0_REC_RKLINK_TX);
- hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk,
- RKX110_SRST_RESETN_D_DSI_0_RKLINK_TX);
- }
-
- if ((route->local_port0 == RK_SERDES_DSI_RX1) ||
- (route->local_port1 == RK_SERDES_DSI_RX1)) {
- serdes->i2c_write_reg(serdes->chip[DEVICE_LOCAL].client, 0x0314,
- 0x2800280);
- hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk,
- RKX111_SRST_RESETN_D_DSI_1_REC_RKLINK_TX);
- hwclk_reset(serdes->chip[DEVICE_LOCAL].hwclk,
- RKX110_SRST_RESETN_D_DSI_1_RKLINK_TX);
- }
- }
- }
-
- return 0;
-}
-
-static int rk_serdes_route_unprepare(struct rk_serdes *serdes, struct rk_serdes_route *route)
-{
- if (route->stream_type == STREAM_DISPLAY) {
- if (route->remote0_port0 & RK_SERDES_DSI_TX0)
- rkx120_dsi_tx_post_disable(serdes, route, DEVICE_REMOTE0);
-
- if (serdes->version == SERDES_V1) {
- if (route->local_port0 == RK_SERDES_DUAL_LVDS_RX) {
- hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk,
- RKX110_SRST_RESETN_2X_LVDS_RKLINK_TX);
- hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk,
- RKX110_SRST_RESETN_D_LVDS0_RKLINK_TX);
- hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk,
- RKX110_SRST_RESETN_D_LVDS1_RKLINK_TX);
- rkx110_set_stream_source(serdes, RK_SERDES_DUAL_LVDS_RX,
- DEVICE_LOCAL);
- }
-
- if ((route->local_port0 == RK_SERDES_DSI_RX0) ||
- (route->local_port1 == RK_SERDES_DSI_RX0)) {
- hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk,
- RKX110_SRST_RESETN_D_DSI_0_RKLINK_TX);
- hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk,
- RKX111_SRST_RESETN_D_DSI_0_REC_RKLINK_TX);
- serdes->i2c_write_reg(serdes->chip[DEVICE_LOCAL].client, 0x0314,
- 0x1400000);
- }
-
- if ((route->local_port0 == RK_SERDES_DSI_RX1) ||
- (route->local_port1 == RK_SERDES_DSI_RX1)) {
- hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk,
- RKX110_SRST_RESETN_D_DSI_1_RKLINK_TX);
- hwclk_reset_deassert(serdes->chip[DEVICE_LOCAL].hwclk,
- RKX111_SRST_RESETN_D_DSI_1_REC_RKLINK_TX);
- serdes->i2c_write_reg(serdes->chip[DEVICE_LOCAL].client, 0x0314,
- 0x2800000);
- }
- }
- }
-
- return 0;
}
static int rk_serdes_set_hwpin(struct rk_serdes *serdes, struct i2c_client *client,
@@ -576,11 +410,17 @@
serdes->i2c_read_reg = rk_serdes_i2c_read;
serdes->i2c_write_reg = rk_serdes_i2c_write;
serdes->i2c_update_bits = rk_serdes_i2c_update_bits;
- serdes->route_prepare = rk_serdes_route_prepare;
- serdes->route_enable = rk_serdes_route_enable;
- serdes->route_disable = rk_serdes_route_disable;
- serdes->route_unprepare = rk_serdes_route_unprepare;
serdes->set_hwpin = rk_serdes_set_hwpin;
+
+ if (rk_serdes_debug_mode(serdes))
+ return;
+
+ if (serdes->stream_type == STREAM_DISPLAY) {
+ serdes->route_prepare = rk_serdes_display_route_prepare;
+ serdes->route_enable = rk_serdes_display_route_enable;
+ serdes->route_disable = rk_serdes_display_route_disable;
+ serdes->route_unprepare = rk_serdes_display_route_unprepare;
+ }
}
static int rk_serdes_passthrough_init(struct rk_serdes *serdes)
@@ -649,6 +489,25 @@
}
kfree(configs);
+ }
+
+ /* config irq passthrough */
+ if (serdes->stream_type == STREAM_DISPLAY) {
+ rkx110_linktx_passthrough_cfg(serdes, DEVICE_LOCAL, RK_SERDES_PASSTHROUGH_IRQ,
+ false);
+ rkx120_linkrx_passthrough_cfg(serdes, DEVICE_REMOTE0, RK_SERDES_PASSTHROUGH_IRQ,
+ true);
+ if (serdes->remote_nr == 2)
+ rkx120_linkrx_passthrough_cfg(serdes, DEVICE_REMOTE1,
+ RK_SERDES_PASSTHROUGH_IRQ, true);
+ } else {
+ rkx120_linkrx_passthrough_cfg(serdes, DEVICE_LOCAL, RK_SERDES_PASSTHROUGH_IRQ,
+ false);
+ rkx110_linktx_passthrough_cfg(serdes, DEVICE_REMOTE0, RK_SERDES_PASSTHROUGH_IRQ,
+ true);
+ if (serdes->remote_nr == 2)
+ rkx110_linktx_passthrough_cfg(serdes, DEVICE_REMOTE1,
+ RK_SERDES_PASSTHROUGH_IRQ, true);
}
return 0;
@@ -903,6 +762,9 @@
i2c_set_clientdata(client, serdes);
}
+ if (serdes->remote_nr == 2)
+ serdes->lane_nr = 2;
+
if (serdes->remote_nr == 0)
return -ENODEV;
@@ -952,14 +814,73 @@
kfree(configs);
}
+ /* config irq pinctrl */
+ if (serdes->stream_type == STREAM_DISPLAY) {
+ serdes->set_hwpin(serdes, serdes->chip[DEVICE_LOCAL].client, PIN_RKX110,
+ RK_SERDES_SER_GPIO_BANK0, RK_SERDES_GPIO_PIN_A4,
+ RK_SERDES_PIN_CONFIG_MUX_FUNC2);
+ serdes->set_hwpin(serdes, serdes->chip[DEVICE_REMOTE0].client, PIN_RKX120,
+ RK_SERDES_DES_GPIO_BANK0, RK_SERDES_GPIO_PIN_A4,
+ RK_SERDES_PIN_CONFIG_MUX_FUNC0);
+ if (serdes->remote_nr == 2)
+ serdes->set_hwpin(serdes, serdes->chip[DEVICE_REMOTE1].client, PIN_RKX120,
+ RK_SERDES_DES_GPIO_BANK0, RK_SERDES_GPIO_PIN_A4,
+ RK_SERDES_PIN_CONFIG_MUX_FUNC0);
+ } else {
+ serdes->set_hwpin(serdes, serdes->chip[DEVICE_REMOTE0].client, PIN_RKX110,
+ RK_SERDES_SER_GPIO_BANK0, RK_SERDES_GPIO_PIN_A4,
+ RK_SERDES_PIN_CONFIG_MUX_FUNC0);
+ serdes->set_hwpin(serdes, serdes->chip[DEVICE_LOCAL].client, PIN_RKX120,
+ RK_SERDES_DES_GPIO_BANK0, RK_SERDES_GPIO_PIN_A4,
+ RK_SERDES_PIN_CONFIG_MUX_FUNC2);
+ if (serdes->remote_nr == 2)
+ serdes->set_hwpin(serdes, serdes->chip[DEVICE_REMOTE1].client, PIN_RKX110,
+ RK_SERDES_SER_GPIO_BANK0, RK_SERDES_GPIO_PIN_A4,
+ RK_SERDES_PIN_CONFIG_MUX_FUNC2);
+ }
+
return 0;
+}
+
+static int rk_serdes_irq_enable(struct rk_serdes *serdes)
+{
+ if (serdes->stream_type == STREAM_DISPLAY)
+ rkx110_irq_enable(serdes, DEVICE_LOCAL);
+ else
+ rkx120_irq_enable(serdes, DEVICE_LOCAL);
+
+ return 0;
+}
+
+__maybe_unused static int rk_serdes_irq_disable(struct rk_serdes *serdes)
+{
+ if (serdes->stream_type == STREAM_DISPLAY)
+ rkx110_irq_disable(serdes, DEVICE_LOCAL);
+ else
+ rkx120_irq_disable(serdes, DEVICE_LOCAL);
+
+ return 0;
+}
+
+static irqreturn_t rk_serdes_irq_handler(int irq, void *arg)
+{
+ struct rk_serdes *serdes = arg;
+
+ if (serdes->stream_type == STREAM_DISPLAY)
+ rkx110_irq_handler(serdes, DEVICE_LOCAL);
+ else
+ rkx120_irq_handler(serdes, DEVICE_LOCAL);
+
+ return IRQ_HANDLED;
}
static int rk_serdes_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct device *dev = &client->dev;
+ struct device_node *disp_np;
struct rk_serdes *serdes;
int ret;
+ bool dual_lane;
serdes = devm_kzalloc(dev, sizeof(*serdes), GFP_KERNEL);
if (!serdes)
@@ -988,6 +909,16 @@
serdes->rate = RATE_2GBPS_83M;
+ serdes->supply = devm_regulator_get_optional(dev, "power");
+ if (IS_ERR(serdes->supply)) {
+ ret = PTR_ERR(serdes->supply);
+
+ if (ret != -ENODEV)
+ return dev_err_probe(dev, ret, "failed to request regulator\n");
+
+ serdes->supply = NULL;
+ }
+
serdes->enable = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW);
if (IS_ERR(serdes->enable)) {
ret = PTR_ERR(serdes->enable);
@@ -1002,15 +933,34 @@
return ret;
}
- gpiod_set_value(serdes->enable, 1);
+ serdes->irq_gpio = devm_gpiod_get_optional(dev, "irq", GPIOD_IN);
+ if (IS_ERR(serdes->irq_gpio)) {
+ ret = PTR_ERR(serdes->irq_gpio);
+ dev_err(dev, "failed to request irq GPIO: %d\n", ret);
+ return ret;
+ }
+ if (serdes->irq_gpio) {
+ serdes->irq = gpiod_to_irq(serdes->irq_gpio);
+ if (serdes->irq < 0)
+ return dev_err_probe(dev, serdes->irq, "failed to get irq\n");
- gpiod_set_value(serdes->reset, 1);
- usleep_range(10000, 11000);
- gpiod_set_value(serdes->reset, 0);
+ irq_set_status_flags(serdes->irq, IRQ_NOAUTOEN);
+ ret = devm_request_threaded_irq(dev, serdes->irq, NULL,
+ rk_serdes_irq_handler,
+ IRQF_TRIGGER_LOW |
+ IRQF_ONESHOT, "serdes-irq", serdes);
+ if (ret) {
+ dev_err(dev, "failed to request serdes interrupt\n");
+ return ret;
+ }
+ } else {
+ dev_warn(dev, "no support serdes irq function\n");
+ }
- if (of_get_child_by_name(dev->of_node, "serdes-panel")) {
+ disp_np = of_get_child_by_name(dev->of_node, "serdes-panel");
+ if (disp_np) {
serdes->stream_type = STREAM_DISPLAY;
- of_node_put(dev->of_node);
+ of_node_put(disp_np);
dev_info(dev, "serdes display stream");
} else {
serdes->stream_type = STREAM_CAMERA;
@@ -1021,7 +971,10 @@
if (ret)
return ret;
- msleep(20);
+ if (serdes->remote_nr != 2) {
+ dual_lane = device_property_read_bool(dev, "dual-lane");
+ serdes->lane_nr = dual_lane ? 2 : 1;
+ }
ret = mfd_add_devices(dev, -1, rkx110_x120_devs, ARRAY_SIZE(rkx110_x120_devs),
NULL, 0, NULL);
@@ -1030,27 +983,58 @@
return ret;
}
+ if (serdes->supply) {
+ ret = regulator_enable(serdes->supply);
+ if (ret < 0) {
+ dev_err(serdes->dev, "failed to enable supply: %d\n", ret);
+ return ret;
+ }
+ }
+
+ gpiod_set_value(serdes->enable, 1);
+
+ gpiod_set_value(serdes->reset, 1);
+ usleep_range(10000, 11000);
+ gpiod_set_value(serdes->reset, 0);
+
+ msleep(20);
+
rk_serdes_wait_link_ready(serdes);
rk_serdes_read_chip_id(serdes);
ret = rk_serdes_add_hwclk(serdes);
if (ret < 0)
- return ret;
+ goto err;
rk_serdes_set_rate(serdes, RATE_4GBPS_83M);
rk_serdes_pinctrl_init(serdes);
rk_serdes_passthrough_init(serdes);
+ rk_serdes_irq_enable(serdes);
+ enable_irq(serdes->irq);
+
+ if (serdes->stream_type == STREAM_DISPLAY)
+ rk_serdes_display_route_init(serdes);
+
out:
rk_serdes_debugfs_init(serdes);
return 0;
+
+err:
+ if (serdes->supply)
+ ret = regulator_disable(serdes->supply);
+
+ return ret;
}
static int rk_serdes_i2c_remove(struct i2c_client *client)
{
struct rk_serdes *rk_serdes = i2c_get_clientdata(client);
+ if (rk_serdes->supply)
+ regulator_disable(rk_serdes->supply);
+
mfd_remove_devices(rk_serdes->dev);
return 0;
--
Gitblit v1.6.2