hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/drivers/gpu/drm/panel/panel-simple.c
....@@ -28,6 +28,7 @@
2828 #include <linux/of_platform.h>
2929 #include <linux/platform_device.h>
3030 #include <linux/regulator/consumer.h>
31
+#include <linux/spi/spi.h>
3132
3233 #include <video/display_timing.h>
3334 #include <video/mipi_display.h>
....@@ -41,6 +42,11 @@
4142 #include <drm/drm_dsc.h>
4243
4344 #include "panel-simple.h"
45
+
46
+enum panel_simple_cmd_type {
47
+ CMD_TYPE_DEFAULT,
48
+ CMD_TYPE_SPI
49
+};
4450
4551 struct panel_cmd_header {
4652 u8 data_type;
....@@ -124,6 +130,11 @@
124130
125131 struct panel_cmd_seq *init_seq;
126132 struct panel_cmd_seq *exit_seq;
133
+
134
+ enum panel_simple_cmd_type cmd_type;
135
+
136
+ int (*spi_read)(struct device *dev, const u8 cmd, u8 *val);
137
+ int (*spi_write)(struct device *dev, const u8 *data, size_t len, u8 type);
127138 };
128139
129140 struct panel_simple {
....@@ -266,7 +277,30 @@
266277 dev_err(dev, "failed to write dcs cmd: %d\n", err);
267278
268279 if (cmd->header.delay)
269
- msleep(cmd->header.delay);
280
+ usleep_range(cmd->header.delay * 1000, cmd->header.delay * 1000 + 100);
281
+ }
282
+
283
+ return 0;
284
+}
285
+
286
+static int panel_simple_xfer_spi_cmd_seq(struct panel_simple *panel, struct panel_cmd_seq *cmds)
287
+{
288
+ int i;
289
+ int ret;
290
+
291
+ if (!cmds)
292
+ return -EINVAL;
293
+
294
+ for (i = 0; i < cmds->cmd_cnt; i++) {
295
+ struct panel_cmd_desc *cmd = &cmds->cmds[i];
296
+
297
+ ret = panel->desc->spi_write(panel->base.dev, cmd->payload,
298
+ cmd->header.payload_length, cmd->header.data_type);
299
+ if (ret)
300
+ return ret;
301
+
302
+ if (cmd->header.delay)
303
+ usleep_range(cmd->header.delay * 1000, cmd->header.delay * 1000 + 100);
270304 }
271305
272306 return 0;
....@@ -444,7 +478,7 @@
444478 return 0;
445479
446480 if (p->desc->delay.disable)
447
- msleep(p->desc->delay.disable);
481
+ usleep_range(p->desc->delay.disable * 1000, p->desc->delay.disable * 1000 + 100);
448482
449483 p->enabled = false;
450484
....@@ -458,9 +492,17 @@
458492 if (!p->prepared)
459493 return 0;
460494
461
- if (p->desc->exit_seq)
462
- if (p->dsi)
463
- panel_simple_xfer_dsi_cmd_seq(p, p->desc->exit_seq);
495
+ if (p->desc->exit_seq) {
496
+ if (p->desc->cmd_type == CMD_TYPE_SPI) {
497
+ if (panel_simple_xfer_spi_cmd_seq(p, p->desc->exit_seq)) {
498
+ dev_err(panel->dev, "failed to send exit spi cmds seq\n");
499
+ return -EINVAL;
500
+ }
501
+ } else {
502
+ if (p->dsi)
503
+ panel_simple_xfer_dsi_cmd_seq(p, p->desc->exit_seq);
504
+ }
505
+ }
464506
465507 gpiod_direction_output(p->reset_gpio, 1);
466508 gpiod_direction_output(p->enable_gpio, 0);
....@@ -468,7 +510,7 @@
468510 panel_simple_regulator_disable(p);
469511
470512 if (p->desc->delay.unprepare)
471
- msleep(p->desc->delay.unprepare);
513
+ usleep_range(p->desc->delay.unprepare * 1000, p->desc->delay.unprepare * 1000 + 100);
472514
473515 p->prepared = false;
474516
....@@ -522,7 +564,7 @@
522564 if (p->no_hpd)
523565 delay += p->desc->delay.hpd_absent_delay;
524566 if (delay)
525
- msleep(delay);
567
+ usleep_range(delay * 1000, delay * 1000 + 100);
526568
527569 if (p->hpd_gpio) {
528570 if (IS_ERR(p->hpd_gpio)) {
....@@ -547,16 +589,24 @@
547589 gpiod_direction_output(p->reset_gpio, 1);
548590
549591 if (p->desc->delay.reset)
550
- msleep(p->desc->delay.reset);
592
+ usleep_range(p->desc->delay.reset * 1000, p->desc->delay.reset * 1000 + 100);
551593
552594 gpiod_direction_output(p->reset_gpio, 0);
553595
554596 if (p->desc->delay.init)
555
- msleep(p->desc->delay.init);
597
+ usleep_range(p->desc->delay.init * 1000, p->desc->delay.init * 1000 + 100);
556598
557
- if (p->desc->init_seq)
558
- if (p->dsi)
559
- panel_simple_xfer_dsi_cmd_seq(p, p->desc->init_seq);
599
+ if (p->desc->init_seq) {
600
+ if (p->desc->cmd_type == CMD_TYPE_SPI) {
601
+ if (panel_simple_xfer_spi_cmd_seq(p, p->desc->init_seq)) {
602
+ dev_err(panel->dev, "failed to send init spi cmds seq\n");
603
+ return -EINVAL;
604
+ }
605
+ } else {
606
+ if (p->dsi)
607
+ panel_simple_xfer_dsi_cmd_seq(p, p->desc->init_seq);
608
+ }
609
+ }
560610
561611 p->prepared = true;
562612
....@@ -571,7 +621,7 @@
571621 return 0;
572622
573623 if (p->desc->delay.enable)
574
- msleep(p->desc->delay.enable);
624
+ usleep_range(p->desc->delay.enable * 1000, p->desc->delay.enable * 1000 + 100);
575625
576626 p->enabled = true;
577627
....@@ -5109,6 +5159,113 @@
51095159 .shutdown = panel_simple_dsi_shutdown,
51105160 };
51115161
5162
+static int panel_simple_spi_read(struct device *dev, const u8 cmd, u8 *data)
5163
+{
5164
+ return 0;
5165
+}
5166
+
5167
+static int panel_simple_spi_write_word(struct device *dev, u16 data)
5168
+{
5169
+ struct spi_device *spi = to_spi_device(dev);
5170
+ struct spi_transfer xfer = {
5171
+ .len = 2,
5172
+ .tx_buf = &data,
5173
+ };
5174
+ struct spi_message msg;
5175
+
5176
+ spi_message_init(&msg);
5177
+ spi_message_add_tail(&xfer, &msg);
5178
+
5179
+ return spi_sync(spi, &msg);
5180
+}
5181
+
5182
+static int panel_simple_spi_write(struct device *dev, const u8 *data, size_t len, u8 type)
5183
+{
5184
+ int ret = 0;
5185
+ int i;
5186
+ u16 mask = type ? 0x100 : 0;
5187
+
5188
+ for (i = 0; i < len; i++) {
5189
+ ret = panel_simple_spi_write_word(dev, *data | mask);
5190
+ if (ret) {
5191
+ dev_err(dev, "failed to write spi seq: %*ph\n", (int)len, data);
5192
+ return ret;
5193
+ }
5194
+ data++;
5195
+ }
5196
+
5197
+ return ret;
5198
+}
5199
+
5200
+static const struct of_device_id panel_simple_spi_of_match[] = {
5201
+ { .compatible = "simple-panel-spi", .data = NULL },
5202
+ { /* sentinel */ }
5203
+};
5204
+MODULE_DEVICE_TABLE(of, panel_simple_spi_of_match);
5205
+
5206
+static int panel_simple_spi_probe(struct spi_device *spi)
5207
+{
5208
+ struct device *dev = &spi->dev;
5209
+ const struct of_device_id *id;
5210
+ const struct panel_desc *desc;
5211
+ struct panel_desc *d;
5212
+ int ret;
5213
+
5214
+ id = of_match_node(panel_simple_spi_of_match, dev->of_node);
5215
+ if (!id)
5216
+ return -ENODEV;
5217
+
5218
+ if (!id->data) {
5219
+ d = devm_kzalloc(dev, sizeof(*d), GFP_KERNEL);
5220
+ if (!d)
5221
+ return -ENOMEM;
5222
+
5223
+ ret = panel_simple_of_get_desc_data(dev, d);
5224
+ if (ret) {
5225
+ dev_err(dev, "failed to get desc data: %d\n", ret);
5226
+ return ret;
5227
+ }
5228
+
5229
+ d->spi_write = panel_simple_spi_write;
5230
+ d->spi_read = panel_simple_spi_read;
5231
+ d->cmd_type = CMD_TYPE_SPI;
5232
+ }
5233
+ desc = id->data ? id->data : d;
5234
+
5235
+ /*
5236
+ * Set spi to 3 lines and 9bits/word mode.
5237
+ */
5238
+ spi->bits_per_word = 9;
5239
+ spi->mode = SPI_MODE_3;
5240
+ ret = spi_setup(spi);
5241
+ if (ret < 0) {
5242
+ dev_err(dev, "spi setup failed.\n");
5243
+ return ret;
5244
+ }
5245
+
5246
+ return panel_simple_probe(dev, desc);
5247
+}
5248
+
5249
+static int panel_simple_spi_remove(struct spi_device *spi)
5250
+{
5251
+ return panel_simple_remove(&spi->dev);
5252
+}
5253
+
5254
+static void panel_simple_spi_shutdown(struct spi_device *spi)
5255
+{
5256
+ panel_simple_shutdown(&spi->dev);
5257
+}
5258
+
5259
+static struct spi_driver panel_simple_spi_driver = {
5260
+ .driver = {
5261
+ .name = "panel-simple-spi",
5262
+ .of_match_table = panel_simple_spi_of_match,
5263
+ },
5264
+ .probe = panel_simple_spi_probe,
5265
+ .remove = panel_simple_spi_remove,
5266
+ .shutdown = panel_simple_spi_shutdown,
5267
+};
5268
+
51125269 static int __init panel_simple_init(void)
51135270 {
51145271 int err;
....@@ -5116,6 +5273,12 @@
51165273 err = platform_driver_register(&panel_simple_platform_driver);
51175274 if (err < 0)
51185275 return err;
5276
+
5277
+ if (IS_ENABLED(CONFIG_SPI_MASTER)) {
5278
+ err = spi_register_driver(&panel_simple_spi_driver);
5279
+ if (err < 0)
5280
+ return err;
5281
+ }
51195282
51205283 if (IS_ENABLED(CONFIG_DRM_MIPI_DSI)) {
51215284 err = mipi_dsi_driver_register(&panel_simple_dsi_driver);
....@@ -5132,6 +5295,9 @@
51325295 if (IS_ENABLED(CONFIG_DRM_MIPI_DSI))
51335296 mipi_dsi_driver_unregister(&panel_simple_dsi_driver);
51345297
5298
+ if (IS_ENABLED(CONFIG_SPI_MASTER))
5299
+ spi_unregister_driver(&panel_simple_spi_driver);
5300
+
51355301 platform_driver_unregister(&panel_simple_platform_driver);
51365302 }
51375303 module_exit(panel_simple_exit);