hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/media/i2c/lt7911d.c
....@@ -49,6 +49,12 @@
4949 #define LT7911D_LINK_FREQ 400000000
5050 #define LT7911D_PIXEL_RATE 400000000
5151
52
+#ifdef LT7911D_OUT_RGB
53
+#define LT7911D_MEDIA_BUS_FMT MEDIA_BUS_FMT_BGR888_1X24
54
+#else
55
+#define LT7911D_MEDIA_BUS_FMT MEDIA_BUS_FMT_UYVY8_2X8
56
+#endif
57
+
5258 #define LT7911D_NAME "LT7911D"
5359
5460 static const s64 link_freq_menu_items[] = {
....@@ -73,7 +79,6 @@
7379 struct clk *xvclk;
7480 struct gpio_desc *reset_gpio;
7581 struct gpio_desc *plugin_det_gpio;
76
- struct gpio_desc *hpd_ctl_gpio;
7782 struct gpio_desc *power_gpio;
7883 struct work_struct work_i2c_poll;
7984 struct timer_list timer;
....@@ -472,22 +477,6 @@
472477 return 0;
473478 }
474479
475
-static void lt7911d_config_hpd(struct v4l2_subdev *sd)
476
-{
477
- struct lt7911d_state *lt7911d = to_state(sd);
478
- bool plugin;
479
-
480
- plugin = tx_5v_power_present(sd);
481
- v4l2_dbg(2, debug, sd, "%s: plugin: %d\n", __func__, plugin);
482
-
483
- if (plugin) {
484
- gpiod_set_value(lt7911d->hpd_ctl_gpio, 1);
485
- } else {
486
- lt7911d->nosignal = true;
487
- gpiod_set_value(lt7911d->hpd_ctl_gpio, 0);
488
- }
489
-}
490
-
491480 static void lt7911d_delayed_work_enable_hotplug(struct work_struct *work)
492481 {
493482 struct delayed_work *dwork = to_delayed_work(work);
....@@ -495,7 +484,7 @@
495484 struct lt7911d_state, delayed_work_enable_hotplug);
496485 struct v4l2_subdev *sd = &lt7911d->sd;
497486
498
- lt7911d_config_hpd(sd);
487
+ v4l2_ctrl_s_ctrl(lt7911d->detect_tx_5v_ctrl, tx_5v_power_present(sd));
499488 }
500489
501490 static void lt7911d_delayed_work_res_change(struct work_struct *work)
....@@ -577,21 +566,6 @@
577566 v4l2_subdev_notify_event(sd, &lt7911d_ev_fmt);
578567 }
579568
580
-static int lt7911d_get_ctrl(struct v4l2_ctrl *ctrl)
581
-{
582
- int ret = -1;
583
- struct lt7911d_state *lt7911d = container_of(ctrl->handler,
584
- struct lt7911d_state, hdl);
585
- struct v4l2_subdev *sd = &(lt7911d->sd);
586
-
587
- if (ctrl->id == V4L2_CID_DV_RX_POWER_PRESENT) {
588
- ret = tx_5v_power_present(sd);
589
- *ctrl->p_new.p_s32 = ret;
590
- }
591
-
592
- return ret;
593
-}
594
-
595569 static int lt7911d_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
596570 {
597571 struct lt7911d_state *lt7911d = to_state(sd);
....@@ -615,12 +589,10 @@
615589 static irqreturn_t plugin_detect_irq_handler(int irq, void *dev_id)
616590 {
617591 struct lt7911d_state *lt7911d = dev_id;
618
- struct v4l2_subdev *sd = &lt7911d->sd;
619592
620593 /* control hpd output level after 25ms */
621594 schedule_delayed_work(&lt7911d->delayed_work_enable_hotplug,
622595 HZ / 40);
623
- tx_5v_power_present(sd);
624596
625597 return IRQ_HANDLED;
626598 }
....@@ -748,11 +720,11 @@
748720 }
749721
750722 static int lt7911d_g_mbus_config(struct v4l2_subdev *sd,
751
- struct v4l2_mbus_config *cfg)
723
+ unsigned int pad, struct v4l2_mbus_config *cfg)
752724 {
753725 struct lt7911d_state *lt7911d = to_state(sd);
754726
755
- cfg->type = V4L2_MBUS_CSI2;
727
+ cfg->type = V4L2_MBUS_CSI2_DPHY;
756728 cfg->flags = V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK |
757729 V4L2_MBUS_CSI2_CHANNEL_0;
758730
....@@ -790,7 +762,7 @@
790762 {
791763 switch (code->index) {
792764 case 0:
793
- code->code = MEDIA_BUS_FMT_UYVY8_2X8;
765
+ code->code = LT7911D_MEDIA_BUS_FMT;
794766 break;
795767
796768 default:
....@@ -807,7 +779,7 @@
807779 if (fse->index >= ARRAY_SIZE(supported_modes))
808780 return -EINVAL;
809781
810
- if (fse->code != MEDIA_BUS_FMT_UYVY8_2X8)
782
+ if (fse->code != LT7911D_MEDIA_BUS_FMT)
811783 return -EINVAL;
812784
813785 fse->min_width = supported_modes[fse->index].width;
....@@ -848,8 +820,7 @@
848820 if (fie->index >= ARRAY_SIZE(supported_modes))
849821 return -EINVAL;
850822
851
- if (fie->code != MEDIA_BUS_FMT_UYVY8_2X8)
852
- return -EINVAL;
823
+ fie->code = LT7911D_MEDIA_BUS_FMT;
853824
854825 fie->width = supported_modes[fie->index].width;
855826 fie->height = supported_modes[fie->index].height;
....@@ -902,7 +873,7 @@
902873 return ret;
903874
904875 switch (code) {
905
- case MEDIA_BUS_FMT_UYVY8_2X8:
876
+ case LT7911D_MEDIA_BUS_FMT:
906877 break;
907878
908879 default:
....@@ -951,6 +922,9 @@
951922 case RKMODULE_GET_MODULE_INFO:
952923 lt7911d_get_module_inf(lt7911d, (struct rkmodule_inf *)arg);
953924 break;
925
+ case RKMODULE_GET_HDMI_MODE:
926
+ *(int *)arg = RKMODULE_HDMIIN_MODE;
927
+ break;
954928 default:
955929 ret = -ENOIOCTLCMD;
956930 break;
....@@ -966,6 +940,7 @@
966940 void __user *up = compat_ptr(arg);
967941 struct rkmodule_inf *inf;
968942 long ret;
943
+ int *seq;
969944
970945 switch (cmd) {
971946 case RKMODULE_GET_MODULE_INFO:
....@@ -983,7 +958,21 @@
983958 }
984959 kfree(inf);
985960 break;
961
+ case RKMODULE_GET_HDMI_MODE:
962
+ seq = kzalloc(sizeof(*seq), GFP_KERNEL);
963
+ if (!seq) {
964
+ ret = -ENOMEM;
965
+ return ret;
966
+ }
986967
968
+ ret = lt7911d_ioctl(sd, cmd, seq);
969
+ if (!ret) {
970
+ ret = copy_to_user(up, seq, sizeof(*seq));
971
+ if (ret)
972
+ ret = -EFAULT;
973
+ }
974
+ kfree(seq);
975
+ break;
987976 default:
988977 ret = -ENOIOCTLCMD;
989978 break;
....@@ -992,10 +981,6 @@
992981 return ret;
993982 }
994983 #endif
995
-
996
-static const struct v4l2_ctrl_ops lt7911d_ctrl_ops = {
997
- .g_volatile_ctrl = lt7911d_get_ctrl,
998
-};
999984
1000985 static const struct v4l2_subdev_core_ops lt7911d_core_ops = {
1001986 .interrupt_service_routine = lt7911d_isr,
....@@ -1012,7 +997,6 @@
1012997 .s_dv_timings = lt7911d_s_dv_timings,
1013998 .g_dv_timings = lt7911d_g_dv_timings,
1014999 .query_dv_timings = lt7911d_query_dv_timings,
1015
- .g_mbus_config = lt7911d_g_mbus_config,
10161000 .s_stream = lt7911d_s_stream,
10171001 .g_frame_interval = lt7911d_g_frame_interval,
10181002 };
....@@ -1025,6 +1009,7 @@
10251009 .get_fmt = lt7911d_get_fmt,
10261010 .enum_dv_timings = lt7911d_enum_dv_timings,
10271011 .dv_timings_cap = lt7911d_dv_timings_cap,
1012
+ .get_mbus_config = lt7911d_g_mbus_config,
10281013 };
10291014
10301015 static const struct v4l2_subdev_ops lt7911d_ops = {
....@@ -1055,16 +1040,6 @@
10551040 .flags = V4L2_CTRL_FLAG_READ_ONLY,
10561041 };
10571042
1058
-static void lt7911d_reset(struct lt7911d_state *lt7911d)
1059
-{
1060
- gpiod_set_value(lt7911d->reset_gpio, 0);
1061
- usleep_range(2000, 2100);
1062
- gpiod_set_value(lt7911d->reset_gpio, 1);
1063
- usleep_range(120*1000, 121*1000);
1064
- gpiod_set_value(lt7911d->reset_gpio, 0);
1065
- usleep_range(300*1000, 310*1000);
1066
-}
1067
-
10681043 static int lt7911d_init_v4l2_ctrls(struct lt7911d_state *lt7911d)
10691044 {
10701045 struct v4l2_subdev *sd;
....@@ -1084,10 +1059,8 @@
10841059 0, LT7911D_PIXEL_RATE, 1, LT7911D_PIXEL_RATE);
10851060
10861061 lt7911d->detect_tx_5v_ctrl = v4l2_ctrl_new_std(&lt7911d->hdl,
1087
- &lt7911d_ctrl_ops, V4L2_CID_DV_RX_POWER_PRESENT,
1062
+ NULL, V4L2_CID_DV_RX_POWER_PRESENT,
10881063 0, 1, 0, 0);
1089
- if (lt7911d->detect_tx_5v_ctrl)
1090
- lt7911d->detect_tx_5v_ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
10911064
10921065 lt7911d->audio_sampling_rate_ctrl =
10931066 v4l2_ctrl_new_custom(&lt7911d->hdl,
....@@ -1119,7 +1092,7 @@
11191092 {
11201093 struct device *dev = &lt7911d->i2c_client->dev;
11211094 struct device_node *node = dev->of_node;
1122
- struct v4l2_fwnode_endpoint *endpoint;
1095
+ struct v4l2_fwnode_endpoint endpoint = { .bus_type = 0 };
11231096 struct device_node *ep;
11241097 int ret;
11251098
....@@ -1160,29 +1133,20 @@
11601133 return ret;
11611134 }
11621135
1163
- lt7911d->hpd_ctl_gpio = devm_gpiod_get_optional(dev, "hpd-ctl",
1164
- GPIOD_OUT_HIGH);
1165
- if (IS_ERR(lt7911d->hpd_ctl_gpio)) {
1166
- dev_err(dev, "failed to get hpd ctl gpio\n");
1167
- ret = PTR_ERR(lt7911d->hpd_ctl_gpio);
1168
- return ret;
1169
- }
1170
-
11711136 ep = of_graph_get_next_endpoint(dev->of_node, NULL);
11721137 if (!ep) {
11731138 dev_err(dev, "missing endpoint node\n");
11741139 return -EINVAL;
11751140 }
11761141
1177
- endpoint = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(ep));
1178
- if (IS_ERR(endpoint)) {
1142
+ ret = v4l2_fwnode_endpoint_alloc_parse(of_fwnode_handle(ep), &endpoint);
1143
+ if (ret) {
11791144 dev_err(dev, "failed to parse endpoint\n");
1180
- ret = PTR_ERR(endpoint);
1181
- return ret;
1145
+ goto put_node;
11821146 }
11831147
1184
- if (endpoint->bus_type != V4L2_MBUS_CSI2 ||
1185
- endpoint->bus.mipi_csi2.num_data_lanes == 0) {
1148
+ if (endpoint.bus_type != V4L2_MBUS_CSI2_DPHY ||
1149
+ endpoint.bus.mipi_csi2.num_data_lanes == 0) {
11861150 dev_err(dev, "missing CSI-2 properties in endpoint\n");
11871151 ret = -EINVAL;
11881152 goto free_endpoint;
....@@ -1201,18 +1165,20 @@
12011165 goto free_endpoint;
12021166 }
12031167
1204
- lt7911d->csi_lanes_in_use = endpoint->bus.mipi_csi2.num_data_lanes;
1205
- lt7911d->bus = endpoint->bus.mipi_csi2;
1168
+ lt7911d->csi_lanes_in_use = endpoint.bus.mipi_csi2.num_data_lanes;
1169
+ lt7911d->bus = endpoint.bus.mipi_csi2;
12061170 lt7911d->enable_hdcp = false;
12071171
1208
- gpiod_set_value(lt7911d->hpd_ctl_gpio, 0);
12091172 gpiod_set_value(lt7911d->power_gpio, 1);
1210
- lt7911d_reset(lt7911d);
1173
+ usleep_range(2000, 3000);
1174
+ gpiod_set_value(lt7911d->reset_gpio, 0);
12111175
12121176 ret = 0;
12131177
12141178 free_endpoint:
1215
- v4l2_fwnode_endpoint_free(endpoint);
1179
+ v4l2_fwnode_endpoint_free(&endpoint);
1180
+put_node:
1181
+ of_node_put(ep);
12161182 return ret;
12171183 }
12181184 #else
....@@ -1266,7 +1232,7 @@
12661232 sd = &lt7911d->sd;
12671233 lt7911d->i2c_client = client;
12681234 lt7911d->cur_mode = &supported_modes[0];
1269
- lt7911d->mbus_fmt_code = MEDIA_BUS_FMT_UYVY8_2X8;
1235
+ lt7911d->mbus_fmt_code = LT7911D_MEDIA_BUS_FMT;
12701236
12711237 err = lt7911d_probe_of(lt7911d);
12721238 if (err) {
....@@ -1277,8 +1243,6 @@
12771243 err = lt7911d_check_chip_id(lt7911d);
12781244 if (err < 0)
12791245 return err;
1280
-
1281
- lt7911d_reset(lt7911d);
12821246
12831247 mutex_init(&lt7911d->confctl_mutex);
12841248 err = lt7911d_init_v4l2_ctrls(lt7911d);
....@@ -1357,7 +1321,6 @@
13571321 goto err_work_queues;
13581322 }
13591323
1360
- lt7911d_config_hpd(sd);
13611324 v4l2_info(sd, "%s found @ 0x%x (%s)\n", client->name,
13621325 client->addr << 1, client->adapter->name);
13631326