Adafruit Adabot 1 year ago
parent
commit
1b2b682f72
4 changed files with 514 additions and 4 deletions
  1. 15
    4
      adafruit-pitft.sh
  2. 78
    0
      overlays/minipitft114-overlay.dts
  3. 14
    0
      st7789_module/Makefile
  4. 407
    0
      st7789_module/st7789v_ada.c

+ 15
- 4
adafruit-pitft.sh View File

@@ -191,7 +191,7 @@ reconfig() {
191 191
 function softwareinstall() {
192 192
     echo "Installing Pre-requisite Software...This may take a few minutes!"
193 193
 		apt-get install -y libts0 1> /dev/null 2>&1 || apt-get install -y tslib 1> /dev/null 2>&1 || { warning "Apt failed to install TSLIB!" && exit 1; }
194
-    apt-get install -y bc fbi git python-dev python-pip python-smbus python-spidev evtest libts-bin 1> /dev/null  || { warning "Apt failed to install software!" && exit 1; }
194
+    apt-get install -y bc fbi git python-dev python-pip python-smbus python-spidev evtest libts-bin device-tree-compiler 1> /dev/null  || { warning "Apt failed to install software!" && exit 1; }
195 195
     pip install evdev 1> /dev/null  || { warning "Pip failed to install software!" && exit 1; }
196 196
 }
197 197
 
@@ -239,6 +239,15 @@ EOF
239 239
         overlay=""
240 240
     fi
241 241
 
242
+    if [ "${pitfttype}" == "st7789_240x135" ]; then
243
+	dtc -@ -I dts -O dtb -o /boot/overlays/drm-minipitft114.dtbo overlays/minipitft114-overlay.dts
244
+	apt-get install -y raspberrypi-kernel-headers 1> /dev/null  || { warning "Apt failed to install software!" && exit 1; }
245
+	cd st7789_module
246
+	make -C /lib/modules/$(uname -r)/build M=$(pwd) modules  || { warning "Apt failed to compile ST7789V driver!" && exit 1; }
247
+	mv /lib/modules/$(uname -r)/kernel/drivers/gpu/drm/tinydrm/mi0283qt.ko /lib/modules/$(uname -r)/kernel/drivers/gpu/drm/tinydrm/mi0283qt.BACK
248
+	mv st7789v_ada.ko /lib/modules/$(uname -r)/kernel/drivers/gpu/drm/tinydrm/mi0283qt.ko
249
+        overlay="dtoverlay=drm-minipitft114,rotation=${pitftrot}"
250
+    fi
242 251
 
243 252
     date=`date`
244 253
 
@@ -495,9 +504,10 @@ selectN "PiTFT 2.4\", 2.8\" or 3.2\" resistive (240x320)" \
495 504
         "PiTFT 2.8\" capacitive touch (240x320)" \
496 505
         "PiTFT 3.5\" resistive touch (320x480)" \
497 506
         "Braincraft 1.54\" display (240x240)" \
507
+        "MiniPiTFT 1.14\" display (240x135)" \
498 508
         "Quit without installing"
499 509
 PITFT_SELECT=$?
500
-if [ $PITFT_SELECT -gt 5 ]; then
510
+if [ $PITFT_SELECT -gt 6 ]; then
501 511
     exit 1
502 512
 fi
503 513
 
@@ -512,7 +522,7 @@ if [ $PITFT_ROTATE -gt 4 ]; then
512 522
 fi
513 523
 
514 524
 PITFT_ROTATIONS=("90" "180" "270" "0")
515
-PITFT_TYPES=("28r" "22" "28c" "35r" "st7789_240x240")
525
+PITFT_TYPES=("28r" "22" "28c" "35r" "st7789_240x240" "st7789_240x135")
516 526
 WIDTH_VALUES=(320 320 320 480 240)
517 527
 HEIGHT_VALUES=(240 240 240 320 240)
518 528
 HZ_VALUES=(64000000 64000000 64000000 32000000 64000000)
@@ -573,13 +583,14 @@ pitfttype=${PITFT_TYPES[$PITFT_SELECT-1]}
573 583
 pitftrot=${PITFT_ROTATIONS[$PITFT_ROTATE-1]}
574 584
 
575 585
 
576
-if [ "${pitfttype}" != "28r" ] && [ "${pitfttype}" != "28c" ] && [ "${pitfttype}" != "35r" ] && [ "${pitfttype}" != "22" ] && [ "${pitfttype}" != "st7789_240x240" ]; then
586
+if [ "${pitfttype}" != "28r" ] && [ "${pitfttype}" != "28c" ] && [ "${pitfttype}" != "35r" ] && [ "${pitfttype}" != "22" ] && [ "${pitfttype}" != "st7789_240x240" ] && [ "${pitfttype}" != "st7789_240x135" ]; then
577 587
     echo "Type must be one of:"
578 588
     echo "  '28r' (2.8\" resistive, PID 1601)"
579 589
     echo "  '28c' (2.8\" capacitive, PID 1983)"
580 590
     echo "  '35r' (3.5\" Resistive)"
581 591
     echo "  '22'  (2.2\" no touch)"
582 592
     echo "  'st7789_240x240' (1.54\" or 1.3\" no touch)"
593
+    echo "  'st7789_240x135' 1.14\" no touch)"
583 594
     echo
584 595
     print_help
585 596
 fi

+ 78
- 0
overlays/minipitft114-overlay.dts View File

@@ -0,0 +1,78 @@
1
+/*
2
+ * Device Tree overlay for Adafruit Mini PiTFT 1.14" Display
3
+ *
4
+ */
5
+
6
+/dts-v1/;
7
+/plugin/;
8
+
9
+/ {
10
+	compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709";
11
+
12
+	fragment@0 {
13
+		target = <&spi0>;
14
+		__overlay__ {
15
+			status = "okay";
16
+
17
+			spidev@0{
18
+				status = "disabled";
19
+			};
20
+
21
+		};
22
+	};
23
+
24
+	fragment@1 {
25
+		target = <&gpio>;
26
+		__overlay__ {
27
+			pitft_pins: pitft_pins {
28
+				brcm,pins = <25>; /* dc pin */
29
+				brcm,function = <1>; /* out */
30
+				brcm,pull = <0>; /* no pull */
31
+			};
32
+		};
33
+	};
34
+
35
+	fragment@2 {
36
+		target = <&spi0>;
37
+		__overlay__ {
38
+			/* needed to avoid dtc warning */
39
+			#address-cells = <1>;
40
+			#size-cells = <0>;
41
+
42
+			pitft: pitft@0{
43
+				compatible = "multi-inno,mi0283qt";
44
+				reg = <0>;
45
+				pinctrl-names = "default";
46
+				pinctrl-0 = <&pitft_pins>;
47
+
48
+				spi-max-frequency = <32000000>;
49
+				rotation = <90>;
50
+				width = <136>;
51
+				height = <240>;
52
+				col_offset = <53>;
53
+				row_offset = <40>;
54
+				dc-gpios = <&gpio 25 0>;
55
+				backlight = <&backlight>;
56
+			};
57
+		};
58
+	};
59
+
60
+	fragment@3 {
61
+		target-path = "/soc";
62
+		__overlay__ {
63
+			backlight: backlight {
64
+				compatible = "gpio-backlight";
65
+				gpios = <&gpio 22 0>;
66
+			};
67
+		};
68
+	};
69
+
70
+	__overrides__ {
71
+		speed =       <&pitft>,"spi-max-frequency:0";
72
+		rotation =    <&pitft>,"rotation:0";
73
+		width =       <&pitft>,"width:0";
74
+		height =      <&pitft>,"height:0";
75
+		col_offset =  <&pitft>,"col_offset:0";
76
+		row_offset =  <&pitft>,"row_offset:0";
77
+	};
78
+};

+ 14
- 0
st7789_module/Makefile View File

@@ -0,0 +1,14 @@
1
+obj-m+=st7789v_ada.o
2
+
3
+KDIR ?= /lib/modules/`uname -r`/build
4
+
5
+default:
6
+	$(MAKE) -C $(KDIR) M=$(pwd) modules
7
+
8
+install:
9
+	$(MAKE) -C $(KDIR) M=$(PWD) modules_install
10
+	$(DEPMOD)
11
+
12
+clean:
13
+	$(MAKE) -C $(KDIR) M=$(PWD) clean
14
+

+ 407
- 0
st7789_module/st7789v_ada.c View File

@@ -0,0 +1,407 @@
1
+/*
2
+ * DRM driver for ST7789V panels with flexible config
3
+ *
4
+ * Copyright 2019 Limor Fried
5
+ * Copyright 2016 Noralf Trønnes
6
+ *
7
+ * This program is free software; you can redistribute it and/or modify
8
+ * it under the terms of the GNU General Public License as published by
9
+ * the Free Software Foundation; either version 2 of the License, or
10
+ * (at your option) any later version.
11
+ */
12
+
13
+#include <linux/backlight.h>
14
+#include <linux/delay.h>
15
+#include <linux/gpio/consumer.h>
16
+#include <linux/module.h>
17
+#include <linux/property.h>
18
+#include <linux/regulator/consumer.h>
19
+#include <linux/spi/spi.h>
20
+
21
+#include <drm/drm_fb_helper.h>
22
+#include <drm/drm_modeset_helper.h>
23
+#include <drm/drm_gem_framebuffer_helper.h>
24
+#include <drm/tinydrm/mipi-dbi.h>
25
+#include <drm/tinydrm/tinydrm-helpers.h>
26
+#include <video/mipi_display.h>
27
+
28
+#define ST77XX_MADCTL_MY  0x80
29
+#define ST77XX_MADCTL_MX  0x40
30
+#define ST77XX_MADCTL_MV  0x20
31
+#define ST77XX_MADCTL_ML  0x10
32
+#define ST77XX_MADCTL_BGR 0x08
33
+#define ST77XX_MADCTL_RGB 0x00
34
+
35
+static u32 col_offset = 0;
36
+static u32 row_offset = 0;
37
+static u8 col_hack_fix_offset = 0;
38
+static short x_offset = 0;
39
+static short y_offset = 0;
40
+
41
+static void st7789vada_enable(struct drm_simple_display_pipe *pipe,
42
+			    struct drm_crtc_state *crtc_state,
43
+			    struct drm_plane_state *plane_state)
44
+{
45
+	struct tinydrm_device *tdev = pipe_to_tinydrm(pipe);
46
+	struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev);
47
+	u8 addr_mode;
48
+	int ret;
49
+
50
+	DRM_DEBUG_KMS("\n");
51
+
52
+	ret = mipi_dbi_poweron_conditional_reset(mipi);
53
+	if (ret < 0)
54
+		return;
55
+	if (ret == 1)
56
+		goto out_enable;
57
+
58
+	mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_OFF);
59
+
60
+	mipi_dbi_command(mipi, MIPI_DCS_SOFT_RESET);
61
+	msleep(150);
62
+	mipi_dbi_command(mipi, MIPI_DCS_EXIT_SLEEP_MODE);
63
+	msleep(10);
64
+	mipi_dbi_command(mipi, MIPI_DCS_SET_PIXEL_FORMAT, 0x55); // 16 bit color
65
+	msleep(10);
66
+	mipi_dbi_command(mipi, MIPI_DCS_SET_ADDRESS_MODE, 0);
67
+	mipi_dbi_command(mipi, MIPI_DCS_SET_COLUMN_ADDRESS, 0, 0, 0, 240);
68
+	mipi_dbi_command(mipi, MIPI_DCS_SET_PAGE_ADDRESS, 0, 0, 320>>8, 320&0xFF);
69
+	mipi_dbi_command(mipi, MIPI_DCS_ENTER_INVERT_MODE); // odd hack, displays are inverted
70
+	mipi_dbi_command(mipi, MIPI_DCS_ENTER_NORMAL_MODE);
71
+	msleep(10);
72
+	mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_ON);
73
+	msleep(10);
74
+
75
+out_enable:
76
+	/* The PiTFT (ili9340) has a hardware reset circuit that
77
+	 * resets only on power-on and not on each reboot through
78
+	 * a gpio like the rpi-display does.
79
+	 * As a result, we need to always apply the rotation value
80
+	 * regardless of the display "on/off" state.
81
+	 */
82
+	switch (mipi->rotation) {
83
+	default:
84
+		addr_mode = 0;
85
+		x_offset = col_offset;
86
+		y_offset = row_offset;
87
+		break;
88
+	case 90:
89
+		addr_mode = ST77XX_MADCTL_MV | ST77XX_MADCTL_MX;
90
+		x_offset = row_offset;
91
+		y_offset = col_offset;
92
+		break;
93
+	case 180:
94
+		addr_mode = ST77XX_MADCTL_MX | ST77XX_MADCTL_MY;
95
+		x_offset = col_offset+col_hack_fix_offset; 
96
+		// hack tweak to account for extra pixel width to make even
97
+		y_offset = row_offset; 
98
+		break;
99
+	case 270:
100
+		addr_mode = ST77XX_MADCTL_MV | ST77XX_MADCTL_MY;
101
+		x_offset = row_offset;
102
+		y_offset = col_offset;
103
+		break;
104
+	}
105
+	mipi_dbi_command(mipi, MIPI_DCS_SET_ADDRESS_MODE, addr_mode);
106
+
107
+	mipi_dbi_command(mipi, MIPI_DCS_SET_DISPLAY_ON);
108
+
109
+	mipi_dbi_enable_flush(mipi, crtc_state, plane_state);
110
+
111
+	backlight_enable(mipi->backlight);
112
+}
113
+
114
+static const struct drm_simple_display_pipe_funcs st7789vada_pipe_funcs = {
115
+	.enable = st7789vada_enable,
116
+	.disable = mipi_dbi_pipe_disable,
117
+	.update = tinydrm_display_pipe_update,
118
+	.prepare_fb = drm_gem_fb_simple_display_pipe_prepare_fb,
119
+};
120
+
121
+static struct drm_display_mode st7789vada_mode = {
122
+  TINYDRM_MODE(240, 320, 25, 15), // width, height, mm_w, mm_h
123
+};
124
+
125
+DEFINE_DRM_GEM_CMA_FOPS(st7789vada_fops);
126
+
127
+static struct drm_driver st7789vada_driver = {
128
+	.driver_features	= DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME |
129
+				  DRIVER_ATOMIC,
130
+	.fops			= &st7789vada_fops,
131
+	TINYDRM_GEM_DRIVER_OPS,
132
+	.debugfs_init		= mipi_dbi_debugfs_init,
133
+	.name			= "st7789vada",
134
+	.desc			= "ST7789V Adafruit",
135
+	.date			= "20190914",
136
+	.major			= 1,
137
+	.minor			= 0,
138
+};
139
+
140
+static const struct of_device_id st7789vada_of_match[] = {
141
+	{ .compatible = "multi-inno,mi0283qt" },
142
+	{},
143
+};
144
+MODULE_DEVICE_TABLE(of, st7789vada_of_match);
145
+
146
+static const struct spi_device_id st7789vada_id[] = {
147
+	{ "st7789vada", 0 },
148
+	{ },
149
+};
150
+MODULE_DEVICE_TABLE(spi, st7789vada_id);
151
+
152
+
153
+static const struct drm_framebuffer_funcs st7789vada_fb_funcs = {
154
+	.destroy	= drm_gem_fb_destroy,
155
+	.create_handle	= drm_gem_fb_create_handle,
156
+	.dirty		= tinydrm_fb_dirty,
157
+};
158
+
159
+static const uint32_t st7789vada_formats[] = {
160
+	DRM_FORMAT_RGB565,
161
+	DRM_FORMAT_XRGB8888,
162
+};
163
+
164
+static int st7789vada_fb_dirty(struct drm_framebuffer *fb,
165
+			     struct drm_file *file_priv,
166
+			     unsigned int flags, unsigned int color,
167
+			     struct drm_clip_rect *clips,
168
+			     unsigned int num_clips)
169
+{
170
+	struct drm_gem_cma_object *cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
171
+	struct tinydrm_device *tdev = fb->dev->dev_private;
172
+	struct mipi_dbi *mipi = mipi_dbi_from_tinydrm(tdev);
173
+	bool swap = mipi->swap_bytes;
174
+	struct drm_clip_rect clip;
175
+	int ret = 0;
176
+	bool full;
177
+	void *tr;
178
+	u16 x1, x2, y1, y2;
179
+
180
+	if (!mipi->enabled)
181
+		return 0;
182
+
183
+	full = tinydrm_merge_clips(&clip, clips, num_clips, flags,
184
+				   fb->width, fb->height);
185
+
186
+	DRM_DEBUG("Flushing [FB:%d] x1=%u, x2=%u, y1=%u, y2=%u\n", fb->base.id,
187
+		  clip.x1, clip.x2, clip.y1, clip.y2);
188
+
189
+	if (!mipi->dc || !full || swap ||
190
+	    fb->format->format == DRM_FORMAT_XRGB8888) {
191
+		tr = mipi->tx_buf;
192
+		ret = mipi_dbi_buf_copy(mipi->tx_buf, fb, &clip, swap);
193
+		if (ret)
194
+			return ret;
195
+	} else {
196
+		tr = cma_obj->vaddr;
197
+	}
198
+
199
+	x1 = clip.x1 + x_offset;
200
+	x2 = clip.x2 - 1 + x_offset;
201
+	y1 = clip.y1 + y_offset;
202
+	y2 = clip.y2 - 1 + y_offset;
203
+
204
+	//printk(KERN_INFO "setaddrwin %d %d %d %d\n", x1, y1, x2, y2);
205
+
206
+	mipi_dbi_command(mipi, MIPI_DCS_SET_COLUMN_ADDRESS,
207
+			 (x1 >> 8) & 0xFF, x1 & 0xFF,
208
+			 (x2 >> 8) & 0xFF, x2 & 0xFF);
209
+	mipi_dbi_command(mipi, MIPI_DCS_SET_PAGE_ADDRESS,
210
+			 (y1 >> 8) & 0xFF, y1 & 0xFF,
211
+			 (y2 >> 8) & 0xFF, y2 & 0xFF);
212
+
213
+	ret = mipi_dbi_command_buf(mipi, MIPI_DCS_WRITE_MEMORY_START, tr,
214
+				(clip.x2 - clip.x1) * (clip.y2 - clip.y1) * 2);
215
+
216
+	return ret;
217
+}
218
+
219
+/**
220
+ * st7789vada - MIPI DBI initialization
221
+ * @dev: Parent device
222
+ * @mipi: &mipi_dbi structure to initialize
223
+ * @pipe_funcs: Display pipe functions
224
+ * @driver: DRM driver
225
+ * @mode: Display mode
226
+ * @rotation: Initial rotation in degrees Counter Clock Wise
227
+ *
228
+ * This function initializes a &mipi_dbi structure and it's underlying
229
+ * @tinydrm_device. It also sets up the display pipeline.
230
+ *
231
+ * Supported formats: Native RGB565 and emulated XRGB8888.
232
+ *
233
+ * Objects created by this function will be automatically freed on driver
234
+ * detach (devres).
235
+ *
236
+ * Returns:
237
+ * Zero on success, negative error code on failure.
238
+ */
239
+int st7789vada_init(struct device *dev, struct mipi_dbi *mipi,
240
+		  const struct drm_simple_display_pipe_funcs *pipe_funcs,
241
+		  struct drm_driver *driver,
242
+		  const struct drm_display_mode *mode, unsigned int rotation)
243
+{
244
+	size_t bufsize = mode->vdisplay * mode->hdisplay * sizeof(u16);
245
+	struct tinydrm_device *tdev = &mipi->tinydrm;
246
+	int ret;
247
+
248
+	if (!mipi->command)
249
+		return -EINVAL;
250
+
251
+	mutex_init(&mipi->cmdlock);
252
+
253
+	mipi->tx_buf = devm_kmalloc(dev, bufsize, GFP_KERNEL);
254
+	if (!mipi->tx_buf)
255
+		return -ENOMEM;
256
+
257
+	ret = devm_tinydrm_init(dev, tdev, &st7789vada_fb_funcs, driver);
258
+	if (ret)
259
+		return ret;
260
+
261
+	tdev->fb_dirty = st7789vada_fb_dirty;
262
+
263
+	/* TODO: Maybe add DRM_MODE_CONNECTOR_SPI */
264
+	ret = tinydrm_display_pipe_init(tdev, pipe_funcs,
265
+					DRM_MODE_CONNECTOR_VIRTUAL,
266
+					st7789vada_formats,
267
+					ARRAY_SIZE(st7789vada_formats), mode,
268
+					rotation);
269
+	if (ret)
270
+		return ret;
271
+
272
+	tdev->drm->mode_config.preferred_depth = 16;
273
+	mipi->rotation = rotation;
274
+
275
+	drm_mode_config_reset(tdev->drm);
276
+
277
+	DRM_DEBUG_KMS("preferred_depth=%u, rotation = %u\n",
278
+		      tdev->drm->mode_config.preferred_depth, rotation);
279
+
280
+	return 0;
281
+}
282
+
283
+static int st7789vada_probe(struct spi_device *spi)
284
+{
285
+	struct device *dev = &spi->dev;
286
+	struct mipi_dbi *mipi;
287
+	struct gpio_desc *dc;
288
+	u32 rotation = 0;
289
+	u32 width = 240;
290
+	u32 height = 320;
291
+	int ret;
292
+
293
+	mipi = devm_kzalloc(dev, sizeof(*mipi), GFP_KERNEL);
294
+	if (!mipi)
295
+		return -ENOMEM;
296
+
297
+	mipi->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
298
+	if (IS_ERR(mipi->reset)) {
299
+		DRM_DEV_ERROR(dev, "Failed to get gpio 'reset'\n");
300
+		return PTR_ERR(mipi->reset);
301
+	}
302
+
303
+	dc = devm_gpiod_get_optional(dev, "dc", GPIOD_OUT_LOW);
304
+	if (IS_ERR(dc)) {
305
+		DRM_DEV_ERROR(dev, "Failed to get gpio 'dc'\n");
306
+		return PTR_ERR(dc);
307
+	}
308
+
309
+	mipi->regulator = devm_regulator_get(dev, "power");
310
+	if (IS_ERR(mipi->regulator))
311
+		return PTR_ERR(mipi->regulator);
312
+
313
+	mipi->backlight = devm_of_find_backlight(dev);
314
+	if (IS_ERR(mipi->backlight))
315
+		return PTR_ERR(mipi->backlight);
316
+
317
+	device_property_read_u32(dev, "rotation", &rotation);
318
+	//printk(KERN_INFO "Rotation %d\n", rotation);
319
+
320
+	device_property_read_u32(dev, "width", &width);
321
+	if (width % 2) {
322
+	  width +=1;	  // odd width will cause a kernel panic
323
+	  col_hack_fix_offset = 1;
324
+	} else {
325
+	  col_hack_fix_offset = 0;
326
+	}
327
+	//printk(KERN_INFO "Width %d\n", width);
328
+	if ((width == 0) || (width > 240)) {
329
+	  width = 240; // default to full framebuff;
330
+	}
331
+	device_property_read_u32(dev, "height", &height);
332
+	//printk(KERN_INFO "Height %d\n", height);
333
+	if ((height == 0) || (height > 320)) {
334
+	  height = 320; // default to full framebuff;
335
+	}
336
+
337
+	st7789vada_mode.hdisplay = st7789vada_mode.hsync_start = 
338
+	  st7789vada_mode.hsync_end = st7789vada_mode.htotal = width;
339
+	st7789vada_mode.vdisplay = st7789vada_mode.vsync_start = 
340
+	  st7789vada_mode.vsync_end = st7789vada_mode.vtotal = height;
341
+
342
+	device_property_read_u32(dev, "col_offset", &col_offset);
343
+	//printk(KERN_INFO "Column offset %d\n", col_offset);
344
+
345
+	device_property_read_u32(dev, "row_offset", &row_offset);
346
+	//printk(KERN_INFO "Row offset %d\n", row_offset);
347
+
348
+	ret = mipi_dbi_spi_init(spi, mipi, dc);
349
+	if (ret)
350
+		return ret;
351
+
352
+	/* Cannot read from this controller via SPI */
353
+	mipi->read_commands = NULL;
354
+
355
+	ret = st7789vada_init(&spi->dev, mipi, &st7789vada_pipe_funcs,
356
+			      &st7789vada_driver, &st7789vada_mode, rotation);
357
+	if (ret)
358
+		return ret;
359
+
360
+	spi_set_drvdata(spi, mipi);
361
+
362
+	return devm_tinydrm_register(&mipi->tinydrm);
363
+}
364
+
365
+static void st7789vada_shutdown(struct spi_device *spi)
366
+{
367
+	struct mipi_dbi *mipi = spi_get_drvdata(spi);
368
+
369
+	tinydrm_shutdown(&mipi->tinydrm);
370
+}
371
+
372
+static int __maybe_unused st7789vada_pm_suspend(struct device *dev)
373
+{
374
+	struct mipi_dbi *mipi = dev_get_drvdata(dev);
375
+
376
+	return drm_mode_config_helper_suspend(mipi->tinydrm.drm);
377
+}
378
+
379
+static int __maybe_unused st7789vada_pm_resume(struct device *dev)
380
+{
381
+	struct mipi_dbi *mipi = dev_get_drvdata(dev);
382
+
383
+	drm_mode_config_helper_resume(mipi->tinydrm.drm);
384
+
385
+	return 0;
386
+}
387
+
388
+static const struct dev_pm_ops st7789vada_pm_ops = {
389
+	SET_SYSTEM_SLEEP_PM_OPS(st7789vada_pm_suspend, st7789vada_pm_resume)
390
+};
391
+
392
+static struct spi_driver st7789vada_spi_driver = {
393
+	.driver = {
394
+		.name = "st7789vada",
395
+		.owner = THIS_MODULE,
396
+		.of_match_table = st7789vada_of_match,
397
+		.pm = &st7789vada_pm_ops,
398
+	},
399
+	.id_table = st7789vada_id,
400
+	.probe = st7789vada_probe,
401
+	.shutdown = st7789vada_shutdown,
402
+};
403
+module_spi_driver(st7789vada_spi_driver);
404
+
405
+MODULE_DESCRIPTION("Sitronix ST7789V Flexible DRM driver");
406
+MODULE_AUTHOR("Limor Fried");
407
+MODULE_LICENSE("GPL");

Loading…
Cancel
Save