hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/drivers/media/i2c/rk628/rk628_csi_v4l2.c
....@@ -26,6 +26,7 @@
2626 #include <linux/version.h>
2727 #include <linux/videodev2.h>
2828 #include <linux/workqueue.h>
29
+#include <linux/rk_hdmirx_class.h>
2930 #include <media/v4l2-controls_rockchip.h>
3031 #include <media/v4l2-ctrls.h>
3132 #include <media/v4l2-device.h>
....@@ -54,10 +55,10 @@
5455 #define EDID_BLOCK_SIZE 128
5556
5657 #define RK628_CSI_LINK_FREQ_LOW 350000000
57
-#define RK628_CSI_LINK_FREQ_HIGH 400000000
58
+#define RK628_CSI_LINK_FREQ_HIGH 600000000
5859 #define RK628_CSI_PIXEL_RATE_LOW 400000000
5960 #define RK628_CSI_PIXEL_RATE_HIGH 600000000
60
-#define MIPI_DATARATE_MBPS_LOW 750
61
+#define MIPI_DATARATE_MBPS_LOW 700
6162 #define MIPI_DATARATE_MBPS_HIGH 1250
6263
6364 #define POLL_INTERVAL_MS 1000
....@@ -126,12 +127,14 @@
126127 bool hpd_output_inverted;
127128 bool avi_rcv_rdy;
128129 bool vid_ints_en;
130
+ bool continues_clk;
129131 struct rk628_hdcp hdcp;
130132 bool i2s_enable_default;
131133 HAUDINFO audio_info;
132134 struct rk628_combtxphy *txphy;
133135 struct rk628_dsi dsi;
134136 const struct rk628_plat_data *plat_data;
137
+ struct device *classdev;
135138 };
136139
137140 struct rk628_csi_mode {
....@@ -152,7 +155,7 @@
152155 .type = V4L2_DV_BT_656_1120,
153156 /* keep this initialization for compatibility with GCC < 4.4.6 */
154157 .reserved = { 0 },
155
- V4L2_INIT_BT_TIMINGS(1, 10000, 1, 10000, 0, 400000000,
158
+ V4L2_INIT_BT_TIMINGS(1, 10000, 1, 10000, 0, 600000000,
156159 V4L2_DV_BT_STD_CEA861 | V4L2_DV_BT_STD_DMT |
157160 V4L2_DV_BT_STD_GTF | V4L2_DV_BT_STD_CVT,
158161 V4L2_DV_BT_CAP_PROGRESSIVE | V4L2_DV_BT_CAP_INTERLACED |
....@@ -194,6 +197,17 @@
194197 0x16, 0x20, 0x58, 0x2C, 0x25, 0x00, 0xC0, 0x6C,
195198 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00,
196199 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC1,
200
+};
201
+
202
+static struct rkmodule_csi_dphy_param rk3588_dcphy_param = {
203
+ .vendor = PHY_VENDOR_SAMSUNG,
204
+ .lp_vol_ref = 0,
205
+ .lp_hys_sw = {3, 0, 0, 0},
206
+ .lp_escclk_pol_sel = {1, 0, 0, 0},
207
+ .skew_data_cal_clk = {0, 3, 3, 3},
208
+ .clk_hs_term_sel = 2,
209
+ .data_hs_term_sel = {2, 2, 2, 2},
210
+ .reserved = {0},
197211 };
198212
199213 static const struct rk628_csi_mode supported_modes[] = {
....@@ -492,6 +506,7 @@
492506 mutex_lock(&csi->confctl_mutex);
493507 csi->avi_rcv_rdy = false;
494508 plugin = tx_5v_power_present(sd);
509
+ v4l2_ctrl_s_ctrl(csi->detect_tx_5v_ctrl, plugin);
495510 v4l2_dbg(1, debug, sd, "%s: 5v_det:%d\n", __func__, plugin);
496511 if (plugin) {
497512 rk628_csi_enable_interrupts(sd, false);
....@@ -872,7 +887,16 @@
872887 BYPASS_SELECT(1));
873888 rk628_i2c_write(csi->rk628, CSITX_CONFIG_DONE, CONFIG_DONE_IMD);
874889 rk628_i2c_write(csi->rk628, CSITX_SYS_CTRL2, VOP_WHOLE_FRM_EN | VSYNC_ENABLE);
875
- rk628_i2c_update_bits(csi->rk628, CSITX_SYS_CTRL3_IMD,
890
+ if (csi->continues_clk)
891
+ rk628_i2c_update_bits(csi->rk628, CSITX_SYS_CTRL3_IMD,
892
+ CONT_MODE_CLK_CLR_MASK |
893
+ CONT_MODE_CLK_SET_MASK |
894
+ NON_CONTINUOUS_MODE_MASK,
895
+ CONT_MODE_CLK_CLR(0) |
896
+ CONT_MODE_CLK_SET(1) |
897
+ NON_CONTINUOUS_MODE(0));
898
+ else
899
+ rk628_i2c_update_bits(csi->rk628, CSITX_SYS_CTRL3_IMD,
876900 CONT_MODE_CLK_CLR_MASK |
877901 CONT_MODE_CLK_SET_MASK |
878902 NON_CONTINUOUS_MODE_MASK,
....@@ -1476,21 +1500,6 @@
14761500 return 0;
14771501 }
14781502
1479
-static int rk628_csi_get_ctrl(struct v4l2_ctrl *ctrl)
1480
-{
1481
- int ret = -1;
1482
- struct rk628_csi *csi = container_of(ctrl->handler, struct rk628_csi,
1483
- hdl);
1484
- struct v4l2_subdev *sd = &(csi->sd);
1485
-
1486
- if (ctrl->id == V4L2_CID_DV_RX_POWER_PRESENT) {
1487
- ret = tx_5v_power_present(sd);
1488
- *ctrl->p_new.p_s32 = ret;
1489
- }
1490
-
1491
- return ret;
1492
-}
1493
-
14941503 static int rk628_csi_enum_frame_sizes(struct v4l2_subdev *sd,
14951504 struct v4l2_subdev_pad_config *cfg,
14961505 struct v4l2_subdev_frame_size_enum *fse)
....@@ -1541,6 +1550,25 @@
15411550 format->format.field = csi->timings.bt.interlaced ?
15421551 V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE;
15431552 mutex_unlock(&csi->confctl_mutex);
1553
+
1554
+ if (((csi->timings.bt.width == 3840) && (csi->timings.bt.height == 2160)) ||
1555
+ csi->csi_lanes_in_use <= 2) {
1556
+ v4l2_dbg(1, debug, sd,
1557
+ "%s res wxh:%dx%d, link freq:%llu, pixrate:%u\n",
1558
+ __func__, csi->timings.bt.width, csi->timings.bt.height,
1559
+ link_freq_menu_items[1], RK628_CSI_PIXEL_RATE_HIGH);
1560
+ __v4l2_ctrl_s_ctrl(csi->link_freq, 1);
1561
+ __v4l2_ctrl_s_ctrl_int64(csi->pixel_rate,
1562
+ RK628_CSI_PIXEL_RATE_HIGH);
1563
+ } else {
1564
+ v4l2_dbg(1, debug, sd,
1565
+ "%s res wxh:%dx%d, link freq:%llu, pixrate:%u\n",
1566
+ __func__, csi->timings.bt.width, csi->timings.bt.height,
1567
+ link_freq_menu_items[0], RK628_CSI_PIXEL_RATE_LOW);
1568
+ __v4l2_ctrl_s_ctrl(csi->link_freq, 0);
1569
+ __v4l2_ctrl_s_ctrl_int64(csi->pixel_rate,
1570
+ RK628_CSI_PIXEL_RATE_LOW);
1571
+ }
15441572
15451573 v4l2_dbg(1, debug, sd, "%s: fmt code:%d, w:%d, h:%d, field code:%d\n",
15461574 __func__, format->format.code, format->format.width,
....@@ -1614,24 +1642,6 @@
16141642 csi->mbus_fmt_code = format->format.code;
16151643 mode = rk628_csi_find_best_fit(format);
16161644 csi->cur_mode = mode;
1617
-
1618
- if ((mode->width == 3840) && (mode->height == 2160)) {
1619
- v4l2_dbg(1, debug, sd,
1620
- "%s res wxh:%dx%d, link freq:%llu, pixrate:%u\n",
1621
- __func__, mode->width, mode->height,
1622
- link_freq_menu_items[1], RK628_CSI_PIXEL_RATE_HIGH);
1623
- __v4l2_ctrl_s_ctrl(csi->link_freq, 1);
1624
- __v4l2_ctrl_s_ctrl_int64(csi->pixel_rate,
1625
- RK628_CSI_PIXEL_RATE_HIGH);
1626
- } else {
1627
- v4l2_dbg(1, debug, sd,
1628
- "%s res wxh:%dx%d, link freq:%llu, pixrate:%u\n",
1629
- __func__, mode->width, mode->height,
1630
- link_freq_menu_items[0], RK628_CSI_PIXEL_RATE_LOW);
1631
- __v4l2_ctrl_s_ctrl(csi->link_freq, 0);
1632
- __v4l2_ctrl_s_ctrl_int64(csi->pixel_rate,
1633
- RK628_CSI_PIXEL_RATE_LOW);
1634
- }
16351645
16361646 enable_stream(sd, false);
16371647
....@@ -1778,10 +1788,28 @@
17781788 {
17791789 struct rk628_csi *csi = to_csi(sd);
17801790 long ret = 0;
1791
+ struct rkmodule_csi_dphy_param *dphy_param;
17811792
17821793 switch (cmd) {
17831794 case RKMODULE_GET_MODULE_INFO:
17841795 rk628_csi_get_module_inf(csi, (struct rkmodule_inf *)arg);
1796
+ break;
1797
+ case RKMODULE_GET_HDMI_MODE:
1798
+ *(int *)arg = RKMODULE_HDMIIN_MODE;
1799
+ break;
1800
+ case RKMODULE_SET_CSI_DPHY_PARAM:
1801
+ dphy_param = (struct rkmodule_csi_dphy_param *)arg;
1802
+ if (dphy_param->vendor == PHY_VENDOR_SAMSUNG)
1803
+ rk3588_dcphy_param = *dphy_param;
1804
+ v4l2_dbg(1, debug, sd,
1805
+ "sensor set dphy param\n");
1806
+ break;
1807
+ case RKMODULE_GET_CSI_DPHY_PARAM:
1808
+ dphy_param = (struct rkmodule_csi_dphy_param *)arg;
1809
+ *dphy_param = rk3588_dcphy_param;
1810
+
1811
+ v4l2_dbg(1, debug, sd,
1812
+ "sensor get dphy param\n");
17851813 break;
17861814 default:
17871815 ret = -ENOIOCTLCMD;
....@@ -1811,6 +1839,10 @@
18111839 rk628_txphy_set_bus_width(csi->rk628, bus_width);
18121840 rk628_txphy_set_mode(csi->rk628, PHY_MODE_VIDEO_MIPI);
18131841
1842
+ if (csi->lane_mbps == MIPI_DATARATE_MBPS_HIGH)
1843
+ mipi_dphy_init_hsmanual(csi->rk628, true);
1844
+ else
1845
+ mipi_dphy_init_hsmanual(csi->rk628, false);
18141846 mipi_dphy_init_hsfreqrange(csi->rk628, csi->lane_mbps);
18151847 usleep_range(1500, 2000);
18161848 rk628_txphy_power_on(csi->rk628);
....@@ -1840,6 +1872,8 @@
18401872 void __user *up = compat_ptr(arg);
18411873 struct rkmodule_inf *inf;
18421874 long ret;
1875
+ int *seq;
1876
+ struct rkmodule_csi_dphy_param *dphy_param;
18431877
18441878 switch (cmd) {
18451879 case RKMODULE_GET_MODULE_INFO:
....@@ -1857,7 +1891,50 @@
18571891 }
18581892 kfree(inf);
18591893 break;
1894
+ case RKMODULE_GET_HDMI_MODE:
1895
+ seq = kzalloc(sizeof(*seq), GFP_KERNEL);
1896
+ if (!seq) {
1897
+ ret = -ENOMEM;
1898
+ return ret;
1899
+ }
18601900
1901
+ ret = rk628_csi_ioctl(sd, cmd, seq);
1902
+ if (!ret) {
1903
+ ret = copy_to_user(up, seq, sizeof(*seq));
1904
+ if (ret)
1905
+ ret = -EFAULT;
1906
+ }
1907
+ kfree(seq);
1908
+ break;
1909
+ case RKMODULE_SET_CSI_DPHY_PARAM:
1910
+ dphy_param = kzalloc(sizeof(*dphy_param), GFP_KERNEL);
1911
+ if (!dphy_param) {
1912
+ ret = -ENOMEM;
1913
+ return ret;
1914
+ }
1915
+
1916
+ ret = copy_from_user(dphy_param, up, sizeof(*dphy_param));
1917
+ if (!ret)
1918
+ ret = rk628_csi_ioctl(sd, cmd, dphy_param);
1919
+ else
1920
+ ret = -EFAULT;
1921
+ kfree(dphy_param);
1922
+ break;
1923
+ case RKMODULE_GET_CSI_DPHY_PARAM:
1924
+ dphy_param = kzalloc(sizeof(*dphy_param), GFP_KERNEL);
1925
+ if (!dphy_param) {
1926
+ ret = -ENOMEM;
1927
+ return ret;
1928
+ }
1929
+
1930
+ ret = rk628_csi_ioctl(sd, cmd, dphy_param);
1931
+ if (!ret) {
1932
+ ret = copy_to_user(up, dphy_param, sizeof(*dphy_param));
1933
+ if (ret)
1934
+ ret = -EFAULT;
1935
+ }
1936
+ kfree(dphy_param);
1937
+ break;
18611938 default:
18621939 ret = -ENOIOCTLCMD;
18631940 break;
....@@ -1866,10 +1943,6 @@
18661943 return ret;
18671944 }
18681945 #endif
1869
-
1870
-static const struct v4l2_ctrl_ops rk628_csi_ctrl_ops = {
1871
- .g_volatile_ctrl = rk628_csi_get_ctrl,
1872
-};
18731946
18741947 static const struct v4l2_subdev_core_ops rk628_csi_core_ops = {
18751948 .interrupt_service_routine = rk628_csi_isr,
....@@ -1971,6 +2044,7 @@
19712044 int ret = -EINVAL;
19722045 bool hdcp1x_enable = false, i2s_enable_default = false;
19732046 bool scaler_en = false;
2047
+ bool continues_clk = false;
19742048
19752049 csi->soc_24M = devm_clk_get(dev, "soc_24M");
19762050 if (csi->soc_24M == ERR_PTR(-ENOENT))
....@@ -1986,21 +2060,21 @@
19862060 if (IS_ERR(csi->enable_gpio)) {
19872061 ret = PTR_ERR(csi->enable_gpio);
19882062 dev_err(dev, "failed to request enable GPIO: %d\n", ret);
1989
- return ret;
2063
+ goto clk_put;
19902064 }
19912065
19922066 csi->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
19932067 if (IS_ERR(csi->reset_gpio)) {
19942068 ret = PTR_ERR(csi->reset_gpio);
19952069 dev_err(dev, "failed to request reset GPIO: %d\n", ret);
1996
- return ret;
2070
+ goto clk_put;
19972071 }
19982072
19992073 csi->power_gpio = devm_gpiod_get_optional(dev, "power", GPIOD_OUT_HIGH);
20002074 if (IS_ERR(csi->power_gpio)) {
20012075 dev_err(dev, "failed to get power gpio\n");
20022076 ret = PTR_ERR(csi->power_gpio);
2003
- return ret;
2077
+ goto clk_put;
20042078 }
20052079
20062080 csi->plugin_det_gpio = devm_gpiod_get_optional(dev, "plugin-det",
....@@ -2008,7 +2082,7 @@
20082082 if (IS_ERR(csi->plugin_det_gpio)) {
20092083 dev_err(dev, "failed to get hdmirx det gpio\n");
20102084 ret = PTR_ERR(csi->plugin_det_gpio);
2011
- return ret;
2085
+ goto clk_put;
20122086 }
20132087
20142088 if (csi->enable_gpio) {
....@@ -2043,10 +2117,14 @@
20432117 if (of_property_read_bool(dev->of_node, "scaler-en"))
20442118 scaler_en = true;
20452119
2120
+ if (of_property_read_bool(dev->of_node, "continues-clk"))
2121
+ continues_clk = true;
2122
+
20462123 ep = of_graph_get_next_endpoint(dev->of_node, NULL);
20472124 if (!ep) {
20482125 dev_err(dev, "missing endpoint node\n");
2049
- return -EINVAL;
2126
+ ret = -EINVAL;
2127
+ goto clk_put;
20502128 }
20512129
20522130 ret = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(ep), &endpoint);
....@@ -2067,6 +2145,7 @@
20672145 csi->scaler_en = scaler_en;
20682146 if (csi->scaler_en)
20692147 csi->timings = dst_timing;
2148
+ csi->continues_clk = continues_clk;
20702149
20712150 csi->rxphy_pwron = false;
20722151 csi->txphy_pwron = false;
....@@ -2080,6 +2159,8 @@
20802159 v4l2_fwnode_endpoint_free(&endpoint);
20812160 put_node:
20822161 of_node_put(ep);
2162
+clk_put:
2163
+ clk_disable_unprepare(csi->soc_24M);
20832164
20842165 return ret;
20852166 }
....@@ -2108,6 +2189,36 @@
21082189 {}
21092190 };
21102191 MODULE_DEVICE_TABLE(of, rk628_csi_of_match);
2192
+
2193
+static bool tx_5v_power_present(struct v4l2_subdev *sd);
2194
+
2195
+static ssize_t audio_rate_show(struct device *dev,
2196
+ struct device_attribute *attr, char *buf)
2197
+{
2198
+ struct rk628_csi *csi = dev_get_drvdata(dev);
2199
+
2200
+ return snprintf(buf, PAGE_SIZE, "%d", rk628_hdmirx_audio_fs(csi->audio_info));
2201
+}
2202
+
2203
+static ssize_t audio_present_show(struct device *dev,
2204
+ struct device_attribute *attr, char *buf)
2205
+{
2206
+ struct rk628_csi *csi = dev_get_drvdata(dev);
2207
+
2208
+ return snprintf(buf, PAGE_SIZE, "%d",
2209
+ tx_5v_power_present(&csi->sd) ?
2210
+ rk628_hdmirx_audio_present(csi->audio_info) : 0);
2211
+}
2212
+
2213
+static DEVICE_ATTR_RO(audio_rate);
2214
+static DEVICE_ATTR_RO(audio_present);
2215
+
2216
+static struct attribute *rk628_attrs[] = {
2217
+ &dev_attr_audio_rate.attr,
2218
+ &dev_attr_audio_present.attr,
2219
+ NULL
2220
+};
2221
+ATTRIBUTE_GROUPS(rk628);
21112222
21122223 static int rk628_csi_probe(struct i2c_client *client,
21132224 const struct i2c_device_id *id)
....@@ -2203,10 +2314,8 @@
22032314 V4L2_CID_PIXEL_RATE, 0, RK628_CSI_PIXEL_RATE_HIGH, 1,
22042315 RK628_CSI_PIXEL_RATE_HIGH);
22052316 csi->detect_tx_5v_ctrl = v4l2_ctrl_new_std(&csi->hdl,
2206
- &rk628_csi_ctrl_ops, V4L2_CID_DV_RX_POWER_PRESENT,
2317
+ NULL, V4L2_CID_DV_RX_POWER_PRESENT,
22072318 0, 1, 0, 0);
2208
- if (csi->detect_tx_5v_ctrl)
2209
- csi->detect_tx_5v_ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
22102319
22112320 /* custom controls */
22122321 csi->audio_sampling_rate_ctrl = v4l2_ctrl_new_custom(&csi->hdl,
....@@ -2255,6 +2364,14 @@
22552364 goto err_hdl;
22562365 }
22572366
2367
+ csi->classdev = device_create_with_groups(rk_hdmirx_class(),
2368
+ dev, MKDEV(0, 0),
2369
+ csi,
2370
+ rk628_groups,
2371
+ "rk628");
2372
+ if (IS_ERR(csi->classdev))
2373
+ goto err_hdl;
2374
+
22582375 INIT_DELAYED_WORK(&csi->delayed_work_enable_hotplug,
22592376 rk628_csi_delayed_work_enable_hotplug);
22602377 INIT_DELAYED_WORK(&csi->delayed_work_res_change,