xref: /linux/drivers/gpu/drm/solomon/ssd130x.c (revision 24b10e5f8e0d2bee1a10fc67011ea5d936c1a389)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * DRM driver for Solomon SSD13xx OLED displays
4  *
5  * Copyright 2022 Red Hat Inc.
6  * Author: Javier Martinez Canillas <javierm@redhat.com>
7  *
8  * Based on drivers/video/fbdev/ssd1307fb.c
9  * Copyright 2012 Free Electrons
10  */
11 
12 #include <linux/backlight.h>
13 #include <linux/bitfield.h>
14 #include <linux/bits.h>
15 #include <linux/delay.h>
16 #include <linux/gpio/consumer.h>
17 #include <linux/property.h>
18 #include <linux/pwm.h>
19 #include <linux/regulator/consumer.h>
20 
21 #include <drm/drm_atomic.h>
22 #include <drm/drm_atomic_helper.h>
23 #include <drm/drm_crtc_helper.h>
24 #include <drm/drm_damage_helper.h>
25 #include <drm/drm_edid.h>
26 #include <drm/drm_fbdev_generic.h>
27 #include <drm/drm_format_helper.h>
28 #include <drm/drm_framebuffer.h>
29 #include <drm/drm_gem_atomic_helper.h>
30 #include <drm/drm_gem_framebuffer_helper.h>
31 #include <drm/drm_gem_shmem_helper.h>
32 #include <drm/drm_managed.h>
33 #include <drm/drm_modes.h>
34 #include <drm/drm_rect.h>
35 #include <drm/drm_probe_helper.h>
36 
37 #include "ssd130x.h"
38 
39 #define DRIVER_NAME	"ssd130x"
40 #define DRIVER_DESC	"DRM driver for Solomon SSD13xx OLED displays"
41 #define DRIVER_DATE	"20220131"
42 #define DRIVER_MAJOR	1
43 #define DRIVER_MINOR	0
44 
45 #define SSD130X_PAGE_HEIGHT 8
46 
47 #define SSD132X_SEGMENT_WIDTH 2
48 
49 /* ssd13xx commands */
50 #define SSD13XX_CONTRAST			0x81
51 #define SSD13XX_SET_SEG_REMAP			0xa0
52 #define SSD13XX_SET_MULTIPLEX_RATIO		0xa8
53 #define SSD13XX_DISPLAY_OFF			0xae
54 #define SSD13XX_DISPLAY_ON			0xaf
55 
56 #define SSD13XX_SET_SEG_REMAP_MASK		GENMASK(0, 0)
57 #define SSD13XX_SET_SEG_REMAP_SET(val)		FIELD_PREP(SSD13XX_SET_SEG_REMAP_MASK, (val))
58 
59 /* ssd130x commands */
60 #define SSD130X_PAGE_COL_START_LOW		0x00
61 #define SSD130X_PAGE_COL_START_HIGH		0x10
62 #define SSD130X_SET_ADDRESS_MODE		0x20
63 #define SSD130X_SET_COL_RANGE			0x21
64 #define SSD130X_SET_PAGE_RANGE			0x22
65 #define SSD130X_SET_LOOKUP_TABLE		0x91
66 #define SSD130X_CHARGE_PUMP			0x8d
67 #define SSD130X_START_PAGE_ADDRESS		0xb0
68 #define SSD130X_SET_COM_SCAN_DIR		0xc0
69 #define SSD130X_SET_DISPLAY_OFFSET		0xd3
70 #define SSD130X_SET_CLOCK_FREQ			0xd5
71 #define SSD130X_SET_AREA_COLOR_MODE		0xd8
72 #define SSD130X_SET_PRECHARGE_PERIOD		0xd9
73 #define SSD130X_SET_COM_PINS_CONFIG		0xda
74 #define SSD130X_SET_VCOMH			0xdb
75 
76 /* ssd130x commands accessors */
77 #define SSD130X_PAGE_COL_START_MASK		GENMASK(3, 0)
78 #define SSD130X_PAGE_COL_START_HIGH_SET(val)	FIELD_PREP(SSD130X_PAGE_COL_START_MASK, (val) >> 4)
79 #define SSD130X_PAGE_COL_START_LOW_SET(val)	FIELD_PREP(SSD130X_PAGE_COL_START_MASK, (val))
80 #define SSD130X_START_PAGE_ADDRESS_MASK		GENMASK(2, 0)
81 #define SSD130X_START_PAGE_ADDRESS_SET(val)	FIELD_PREP(SSD130X_START_PAGE_ADDRESS_MASK, (val))
82 #define SSD130X_SET_COM_SCAN_DIR_MASK		GENMASK(3, 3)
83 #define SSD130X_SET_COM_SCAN_DIR_SET(val)	FIELD_PREP(SSD130X_SET_COM_SCAN_DIR_MASK, (val))
84 #define SSD130X_SET_CLOCK_DIV_MASK		GENMASK(3, 0)
85 #define SSD130X_SET_CLOCK_DIV_SET(val)		FIELD_PREP(SSD130X_SET_CLOCK_DIV_MASK, (val))
86 #define SSD130X_SET_CLOCK_FREQ_MASK		GENMASK(7, 4)
87 #define SSD130X_SET_CLOCK_FREQ_SET(val)		FIELD_PREP(SSD130X_SET_CLOCK_FREQ_MASK, (val))
88 #define SSD130X_SET_PRECHARGE_PERIOD1_MASK	GENMASK(3, 0)
89 #define SSD130X_SET_PRECHARGE_PERIOD1_SET(val)	FIELD_PREP(SSD130X_SET_PRECHARGE_PERIOD1_MASK, (val))
90 #define SSD130X_SET_PRECHARGE_PERIOD2_MASK	GENMASK(7, 4)
91 #define SSD130X_SET_PRECHARGE_PERIOD2_SET(val)	FIELD_PREP(SSD130X_SET_PRECHARGE_PERIOD2_MASK, (val))
92 #define SSD130X_SET_COM_PINS_CONFIG1_MASK	GENMASK(4, 4)
93 #define SSD130X_SET_COM_PINS_CONFIG1_SET(val)	FIELD_PREP(SSD130X_SET_COM_PINS_CONFIG1_MASK, (val))
94 #define SSD130X_SET_COM_PINS_CONFIG2_MASK	GENMASK(5, 5)
95 #define SSD130X_SET_COM_PINS_CONFIG2_SET(val)	FIELD_PREP(SSD130X_SET_COM_PINS_CONFIG2_MASK, (val))
96 
97 #define SSD130X_SET_ADDRESS_MODE_HORIZONTAL	0x00
98 #define SSD130X_SET_ADDRESS_MODE_VERTICAL	0x01
99 #define SSD130X_SET_ADDRESS_MODE_PAGE		0x02
100 
101 #define SSD130X_SET_AREA_COLOR_MODE_ENABLE	0x1e
102 #define SSD130X_SET_AREA_COLOR_MODE_LOW_POWER	0x05
103 
104 /* ssd132x commands */
105 #define SSD132X_SET_COL_RANGE			0x15
106 #define SSD132X_SET_DEACTIVATE_SCROLL		0x2e
107 #define SSD132X_SET_ROW_RANGE			0x75
108 #define SSD132X_SET_DISPLAY_START		0xa1
109 #define SSD132X_SET_DISPLAY_OFFSET		0xa2
110 #define SSD132X_SET_DISPLAY_NORMAL		0xa4
111 #define SSD132X_SET_FUNCTION_SELECT_A		0xab
112 #define SSD132X_SET_PHASE_LENGTH		0xb1
113 #define SSD132X_SET_CLOCK_FREQ			0xb3
114 #define SSD132X_SET_GPIO			0xb5
115 #define SSD132X_SET_PRECHARGE_PERIOD		0xb6
116 #define SSD132X_SET_GRAY_SCALE_TABLE		0xb8
117 #define SSD132X_SELECT_DEFAULT_TABLE		0xb9
118 #define SSD132X_SET_PRECHARGE_VOLTAGE		0xbc
119 #define SSD130X_SET_VCOMH_VOLTAGE		0xbe
120 #define SSD132X_SET_FUNCTION_SELECT_B		0xd5
121 
122 #define MAX_CONTRAST 255
123 
124 const struct ssd130x_deviceinfo ssd130x_variants[] = {
125 	[SH1106_ID] = {
126 		.default_vcomh = 0x40,
127 		.default_dclk_div = 1,
128 		.default_dclk_frq = 5,
129 		.default_width = 132,
130 		.default_height = 64,
131 		.page_mode_only = 1,
132 		.family_id = SSD130X_FAMILY,
133 	},
134 	[SSD1305_ID] = {
135 		.default_vcomh = 0x34,
136 		.default_dclk_div = 1,
137 		.default_dclk_frq = 7,
138 		.default_width = 132,
139 		.default_height = 64,
140 		.family_id = SSD130X_FAMILY,
141 	},
142 	[SSD1306_ID] = {
143 		.default_vcomh = 0x20,
144 		.default_dclk_div = 1,
145 		.default_dclk_frq = 8,
146 		.need_chargepump = 1,
147 		.default_width = 128,
148 		.default_height = 64,
149 		.family_id = SSD130X_FAMILY,
150 	},
151 	[SSD1307_ID] = {
152 		.default_vcomh = 0x20,
153 		.default_dclk_div = 2,
154 		.default_dclk_frq = 12,
155 		.need_pwm = 1,
156 		.default_width = 128,
157 		.default_height = 39,
158 		.family_id = SSD130X_FAMILY,
159 	},
160 	[SSD1309_ID] = {
161 		.default_vcomh = 0x34,
162 		.default_dclk_div = 1,
163 		.default_dclk_frq = 10,
164 		.default_width = 128,
165 		.default_height = 64,
166 		.family_id = SSD130X_FAMILY,
167 	},
168 	/* ssd132x family */
169 	[SSD1322_ID] = {
170 		.default_width = 480,
171 		.default_height = 128,
172 		.family_id = SSD132X_FAMILY,
173 	},
174 	[SSD1325_ID] = {
175 		.default_width = 128,
176 		.default_height = 80,
177 		.family_id = SSD132X_FAMILY,
178 	},
179 	[SSD1327_ID] = {
180 		.default_width = 128,
181 		.default_height = 128,
182 		.family_id = SSD132X_FAMILY,
183 	}
184 };
185 EXPORT_SYMBOL_NS_GPL(ssd130x_variants, DRM_SSD130X);
186 
187 struct ssd130x_crtc_state {
188 	struct drm_crtc_state base;
189 	/* Buffer to store pixels in HW format and written to the panel */
190 	u8 *data_array;
191 };
192 
193 struct ssd130x_plane_state {
194 	struct drm_shadow_plane_state base;
195 	/* Intermediate buffer to convert pixels from XRGB8888 to HW format */
196 	u8 *buffer;
197 };
198 
199 static inline struct ssd130x_crtc_state *to_ssd130x_crtc_state(struct drm_crtc_state *state)
200 {
201 	return container_of(state, struct ssd130x_crtc_state, base);
202 }
203 
204 static inline struct ssd130x_plane_state *to_ssd130x_plane_state(struct drm_plane_state *state)
205 {
206 	return container_of(state, struct ssd130x_plane_state, base.base);
207 }
208 
209 static inline struct ssd130x_device *drm_to_ssd130x(struct drm_device *drm)
210 {
211 	return container_of(drm, struct ssd130x_device, drm);
212 }
213 
214 /*
215  * Helper to write data (SSD13XX_DATA) to the device.
216  */
217 static int ssd130x_write_data(struct ssd130x_device *ssd130x, u8 *values, int count)
218 {
219 	return regmap_bulk_write(ssd130x->regmap, SSD13XX_DATA, values, count);
220 }
221 
222 /*
223  * Helper to write command (SSD13XX_COMMAND). The fist variadic argument
224  * is the command to write and the following are the command options.
225  *
226  * Note that the ssd13xx protocol requires each command and option to be
227  * written as a SSD13XX_COMMAND device register value. That is why a call
228  * to regmap_write(..., SSD13XX_COMMAND, ...) is done for each argument.
229  */
230 static int ssd130x_write_cmd(struct ssd130x_device *ssd130x, int count,
231 			     /* u8 cmd, u8 option, ... */...)
232 {
233 	va_list ap;
234 	u8 value;
235 	int ret;
236 
237 	va_start(ap, count);
238 
239 	do {
240 		value = va_arg(ap, int);
241 		ret = regmap_write(ssd130x->regmap, SSD13XX_COMMAND, value);
242 		if (ret)
243 			goto out_end;
244 	} while (--count);
245 
246 out_end:
247 	va_end(ap);
248 
249 	return ret;
250 }
251 
252 /* Set address range for horizontal/vertical addressing modes */
253 static int ssd130x_set_col_range(struct ssd130x_device *ssd130x,
254 				 u8 col_start, u8 cols)
255 {
256 	u8 col_end = col_start + cols - 1;
257 	int ret;
258 
259 	if (col_start == ssd130x->col_start && col_end == ssd130x->col_end)
260 		return 0;
261 
262 	ret = ssd130x_write_cmd(ssd130x, 3, SSD130X_SET_COL_RANGE, col_start, col_end);
263 	if (ret < 0)
264 		return ret;
265 
266 	ssd130x->col_start = col_start;
267 	ssd130x->col_end = col_end;
268 	return 0;
269 }
270 
271 static int ssd130x_set_page_range(struct ssd130x_device *ssd130x,
272 				  u8 page_start, u8 pages)
273 {
274 	u8 page_end = page_start + pages - 1;
275 	int ret;
276 
277 	if (page_start == ssd130x->page_start && page_end == ssd130x->page_end)
278 		return 0;
279 
280 	ret = ssd130x_write_cmd(ssd130x, 3, SSD130X_SET_PAGE_RANGE, page_start, page_end);
281 	if (ret < 0)
282 		return ret;
283 
284 	ssd130x->page_start = page_start;
285 	ssd130x->page_end = page_end;
286 	return 0;
287 }
288 
289 /* Set page and column start address for page addressing mode */
290 static int ssd130x_set_page_pos(struct ssd130x_device *ssd130x,
291 				u8 page_start, u8 col_start)
292 {
293 	int ret;
294 	u32 page, col_low, col_high;
295 
296 	page = SSD130X_START_PAGE_ADDRESS |
297 	       SSD130X_START_PAGE_ADDRESS_SET(page_start);
298 	col_low = SSD130X_PAGE_COL_START_LOW |
299 		  SSD130X_PAGE_COL_START_LOW_SET(col_start);
300 	col_high = SSD130X_PAGE_COL_START_HIGH |
301 		   SSD130X_PAGE_COL_START_HIGH_SET(col_start);
302 	ret = ssd130x_write_cmd(ssd130x, 3, page, col_low, col_high);
303 	if (ret < 0)
304 		return ret;
305 
306 	return 0;
307 }
308 
309 static int ssd130x_pwm_enable(struct ssd130x_device *ssd130x)
310 {
311 	struct device *dev = ssd130x->dev;
312 	struct pwm_state pwmstate;
313 
314 	ssd130x->pwm = pwm_get(dev, NULL);
315 	if (IS_ERR(ssd130x->pwm)) {
316 		dev_err(dev, "Could not get PWM from firmware description!\n");
317 		return PTR_ERR(ssd130x->pwm);
318 	}
319 
320 	pwm_init_state(ssd130x->pwm, &pwmstate);
321 	pwm_set_relative_duty_cycle(&pwmstate, 50, 100);
322 	pwm_apply_might_sleep(ssd130x->pwm, &pwmstate);
323 
324 	/* Enable the PWM */
325 	pwm_enable(ssd130x->pwm);
326 
327 	dev_dbg(dev, "Using PWM %s with a %lluns period.\n",
328 		ssd130x->pwm->label, pwm_get_period(ssd130x->pwm));
329 
330 	return 0;
331 }
332 
333 static void ssd130x_reset(struct ssd130x_device *ssd130x)
334 {
335 	if (!ssd130x->reset)
336 		return;
337 
338 	/* Reset the screen */
339 	gpiod_set_value_cansleep(ssd130x->reset, 1);
340 	udelay(4);
341 	gpiod_set_value_cansleep(ssd130x->reset, 0);
342 	udelay(4);
343 }
344 
345 static int ssd130x_power_on(struct ssd130x_device *ssd130x)
346 {
347 	struct device *dev = ssd130x->dev;
348 	int ret;
349 
350 	ssd130x_reset(ssd130x);
351 
352 	ret = regulator_enable(ssd130x->vcc_reg);
353 	if (ret) {
354 		dev_err(dev, "Failed to enable VCC: %d\n", ret);
355 		return ret;
356 	}
357 
358 	if (ssd130x->device_info->need_pwm) {
359 		ret = ssd130x_pwm_enable(ssd130x);
360 		if (ret) {
361 			dev_err(dev, "Failed to enable PWM: %d\n", ret);
362 			regulator_disable(ssd130x->vcc_reg);
363 			return ret;
364 		}
365 	}
366 
367 	return 0;
368 }
369 
370 static void ssd130x_power_off(struct ssd130x_device *ssd130x)
371 {
372 	pwm_disable(ssd130x->pwm);
373 	pwm_put(ssd130x->pwm);
374 
375 	regulator_disable(ssd130x->vcc_reg);
376 }
377 
378 static int ssd130x_init(struct ssd130x_device *ssd130x)
379 {
380 	u32 precharge, dclk, com_invdir, compins, chargepump, seg_remap;
381 	bool scan_mode;
382 	int ret;
383 
384 	/* Set initial contrast */
385 	ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_CONTRAST, ssd130x->contrast);
386 	if (ret < 0)
387 		return ret;
388 
389 	/* Set segment re-map */
390 	seg_remap = (SSD13XX_SET_SEG_REMAP |
391 		     SSD13XX_SET_SEG_REMAP_SET(ssd130x->seg_remap));
392 	ret = ssd130x_write_cmd(ssd130x, 1, seg_remap);
393 	if (ret < 0)
394 		return ret;
395 
396 	/* Set COM direction */
397 	com_invdir = (SSD130X_SET_COM_SCAN_DIR |
398 		      SSD130X_SET_COM_SCAN_DIR_SET(ssd130x->com_invdir));
399 	ret = ssd130x_write_cmd(ssd130x,  1, com_invdir);
400 	if (ret < 0)
401 		return ret;
402 
403 	/* Set multiplex ratio value */
404 	ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_SET_MULTIPLEX_RATIO, ssd130x->height - 1);
405 	if (ret < 0)
406 		return ret;
407 
408 	/* set display offset value */
409 	ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_DISPLAY_OFFSET, ssd130x->com_offset);
410 	if (ret < 0)
411 		return ret;
412 
413 	/* Set clock frequency */
414 	dclk = (SSD130X_SET_CLOCK_DIV_SET(ssd130x->dclk_div - 1) |
415 		SSD130X_SET_CLOCK_FREQ_SET(ssd130x->dclk_frq));
416 	ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_CLOCK_FREQ, dclk);
417 	if (ret < 0)
418 		return ret;
419 
420 	/* Set Area Color Mode ON/OFF & Low Power Display Mode */
421 	if (ssd130x->area_color_enable || ssd130x->low_power) {
422 		u32 mode = 0;
423 
424 		if (ssd130x->area_color_enable)
425 			mode |= SSD130X_SET_AREA_COLOR_MODE_ENABLE;
426 
427 		if (ssd130x->low_power)
428 			mode |= SSD130X_SET_AREA_COLOR_MODE_LOW_POWER;
429 
430 		ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_AREA_COLOR_MODE, mode);
431 		if (ret < 0)
432 			return ret;
433 	}
434 
435 	/* Set precharge period in number of ticks from the internal clock */
436 	precharge = (SSD130X_SET_PRECHARGE_PERIOD1_SET(ssd130x->prechargep1) |
437 		     SSD130X_SET_PRECHARGE_PERIOD2_SET(ssd130x->prechargep2));
438 	ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_PRECHARGE_PERIOD, precharge);
439 	if (ret < 0)
440 		return ret;
441 
442 	/* Set COM pins configuration */
443 	compins = BIT(1);
444 	/*
445 	 * The COM scan mode field values are the inverse of the boolean DT
446 	 * property "solomon,com-seq". The value 0b means scan from COM0 to
447 	 * COM[N - 1] while 1b means scan from COM[N - 1] to COM0.
448 	 */
449 	scan_mode = !ssd130x->com_seq;
450 	compins |= (SSD130X_SET_COM_PINS_CONFIG1_SET(scan_mode) |
451 		    SSD130X_SET_COM_PINS_CONFIG2_SET(ssd130x->com_lrremap));
452 	ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_COM_PINS_CONFIG, compins);
453 	if (ret < 0)
454 		return ret;
455 
456 	/* Set VCOMH */
457 	ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_VCOMH, ssd130x->vcomh);
458 	if (ret < 0)
459 		return ret;
460 
461 	/* Turn on the DC-DC Charge Pump */
462 	chargepump = BIT(4);
463 
464 	if (ssd130x->device_info->need_chargepump)
465 		chargepump |= BIT(2);
466 
467 	ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_CHARGE_PUMP, chargepump);
468 	if (ret < 0)
469 		return ret;
470 
471 	/* Set lookup table */
472 	if (ssd130x->lookup_table_set) {
473 		int i;
474 
475 		ret = ssd130x_write_cmd(ssd130x, 1, SSD130X_SET_LOOKUP_TABLE);
476 		if (ret < 0)
477 			return ret;
478 
479 		for (i = 0; i < ARRAY_SIZE(ssd130x->lookup_table); i++) {
480 			u8 val = ssd130x->lookup_table[i];
481 
482 			if (val < 31 || val > 63)
483 				dev_warn(ssd130x->dev,
484 					 "lookup table index %d value out of range 31 <= %d <= 63\n",
485 					 i, val);
486 			ret = ssd130x_write_cmd(ssd130x, 1, val);
487 			if (ret < 0)
488 				return ret;
489 		}
490 	}
491 
492 	/* Switch to page addressing mode */
493 	if (ssd130x->page_address_mode)
494 		return ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_ADDRESS_MODE,
495 					 SSD130X_SET_ADDRESS_MODE_PAGE);
496 
497 	/* Switch to horizontal addressing mode */
498 	return ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_ADDRESS_MODE,
499 				 SSD130X_SET_ADDRESS_MODE_HORIZONTAL);
500 }
501 
502 static int ssd132x_init(struct ssd130x_device *ssd130x)
503 {
504 	int ret;
505 
506 	/* Set initial contrast */
507 	ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_CONTRAST, 0x80);
508 	if (ret < 0)
509 		return ret;
510 
511 	/* Set column start and end */
512 	ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_COL_RANGE, 0x00,
513 				ssd130x->width / SSD132X_SEGMENT_WIDTH - 1);
514 	if (ret < 0)
515 		return ret;
516 
517 	/* Set row start and end */
518 	ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_ROW_RANGE, 0x00, ssd130x->height - 1);
519 	if (ret < 0)
520 		return ret;
521 	/*
522 	 * Horizontal Address Increment
523 	 * Re-map for Column Address, Nibble and COM
524 	 * COM Split Odd Even
525 	 */
526 	ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_SET_SEG_REMAP, 0x53);
527 	if (ret < 0)
528 		return ret;
529 
530 	/* Set display start and offset */
531 	ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_DISPLAY_START, 0x00);
532 	if (ret < 0)
533 		return ret;
534 
535 	ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_DISPLAY_OFFSET, 0x00);
536 	if (ret < 0)
537 		return ret;
538 
539 	/* Set display mode normal */
540 	ret = ssd130x_write_cmd(ssd130x, 1, SSD132X_SET_DISPLAY_NORMAL);
541 	if (ret < 0)
542 		return ret;
543 
544 	/* Set multiplex ratio value */
545 	ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_SET_MULTIPLEX_RATIO, ssd130x->height - 1);
546 	if (ret < 0)
547 		return ret;
548 
549 	/* Set phase length */
550 	ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_PHASE_LENGTH, 0x55);
551 	if (ret < 0)
552 		return ret;
553 
554 	/* Select default linear gray scale table */
555 	ret = ssd130x_write_cmd(ssd130x, 1, SSD132X_SELECT_DEFAULT_TABLE);
556 	if (ret < 0)
557 		return ret;
558 
559 	/* Set clock frequency */
560 	ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_CLOCK_FREQ, 0x01);
561 	if (ret < 0)
562 		return ret;
563 
564 	/* Enable internal VDD regulator */
565 	ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_FUNCTION_SELECT_A, 0x1);
566 	if (ret < 0)
567 		return ret;
568 
569 	/* Set pre-charge period */
570 	ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_PRECHARGE_PERIOD, 0x01);
571 	if (ret < 0)
572 		return ret;
573 
574 	/* Set pre-charge voltage */
575 	ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_PRECHARGE_VOLTAGE, 0x08);
576 	if (ret < 0)
577 		return ret;
578 
579 	/* Set VCOMH voltage */
580 	ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_VCOMH_VOLTAGE, 0x07);
581 	if (ret < 0)
582 		return ret;
583 
584 	/* Enable second pre-charge and internal VSL */
585 	ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_FUNCTION_SELECT_B, 0x62);
586 	if (ret < 0)
587 		return ret;
588 
589 	return 0;
590 }
591 
592 static int ssd130x_update_rect(struct ssd130x_device *ssd130x,
593 			       struct drm_rect *rect, u8 *buf,
594 			       u8 *data_array)
595 {
596 	unsigned int x = rect->x1;
597 	unsigned int y = rect->y1;
598 	unsigned int width = drm_rect_width(rect);
599 	unsigned int height = drm_rect_height(rect);
600 	unsigned int line_length = DIV_ROUND_UP(width, 8);
601 	unsigned int page_height = SSD130X_PAGE_HEIGHT;
602 	unsigned int pages = DIV_ROUND_UP(height, page_height);
603 	struct drm_device *drm = &ssd130x->drm;
604 	u32 array_idx = 0;
605 	int ret, i, j, k;
606 
607 	drm_WARN_ONCE(drm, y % page_height != 0, "y must be aligned to screen page\n");
608 
609 	/*
610 	 * The screen is divided in pages, each having a height of 8
611 	 * pixels, and the width of the screen. When sending a byte of
612 	 * data to the controller, it gives the 8 bits for the current
613 	 * column. I.e, the first byte are the 8 bits of the first
614 	 * column, then the 8 bits for the second column, etc.
615 	 *
616 	 *
617 	 * Representation of the screen, assuming it is 5 bits
618 	 * wide. Each letter-number combination is a bit that controls
619 	 * one pixel.
620 	 *
621 	 * A0 A1 A2 A3 A4
622 	 * B0 B1 B2 B3 B4
623 	 * C0 C1 C2 C3 C4
624 	 * D0 D1 D2 D3 D4
625 	 * E0 E1 E2 E3 E4
626 	 * F0 F1 F2 F3 F4
627 	 * G0 G1 G2 G3 G4
628 	 * H0 H1 H2 H3 H4
629 	 *
630 	 * If you want to update this screen, you need to send 5 bytes:
631 	 *  (1) A0 B0 C0 D0 E0 F0 G0 H0
632 	 *  (2) A1 B1 C1 D1 E1 F1 G1 H1
633 	 *  (3) A2 B2 C2 D2 E2 F2 G2 H2
634 	 *  (4) A3 B3 C3 D3 E3 F3 G3 H3
635 	 *  (5) A4 B4 C4 D4 E4 F4 G4 H4
636 	 */
637 
638 	if (!ssd130x->page_address_mode) {
639 		u8 page_start;
640 
641 		/* Set address range for horizontal addressing mode */
642 		ret = ssd130x_set_col_range(ssd130x, ssd130x->col_offset + x, width);
643 		if (ret < 0)
644 			return ret;
645 
646 		page_start = ssd130x->page_offset + y / page_height;
647 		ret = ssd130x_set_page_range(ssd130x, page_start, pages);
648 		if (ret < 0)
649 			return ret;
650 	}
651 
652 	for (i = 0; i < pages; i++) {
653 		int m = page_height;
654 
655 		/* Last page may be partial */
656 		if (page_height * (y / page_height + i + 1) > ssd130x->height)
657 			m = ssd130x->height % page_height;
658 
659 		for (j = 0; j < width; j++) {
660 			u8 data = 0;
661 
662 			for (k = 0; k < m; k++) {
663 				u32 idx = (page_height * i + k) * line_length + j / 8;
664 				u8 byte = buf[idx];
665 				u8 bit = (byte >> (j % 8)) & 1;
666 
667 				data |= bit << k;
668 			}
669 			data_array[array_idx++] = data;
670 		}
671 
672 		/*
673 		 * In page addressing mode, the start address needs to be reset,
674 		 * and each page then needs to be written out separately.
675 		 */
676 		if (ssd130x->page_address_mode) {
677 			ret = ssd130x_set_page_pos(ssd130x,
678 						   ssd130x->page_offset + i,
679 						   ssd130x->col_offset + x);
680 			if (ret < 0)
681 				return ret;
682 
683 			ret = ssd130x_write_data(ssd130x, data_array, width);
684 			if (ret < 0)
685 				return ret;
686 
687 			array_idx = 0;
688 		}
689 	}
690 
691 	/* Write out update in one go if we aren't using page addressing mode */
692 	if (!ssd130x->page_address_mode)
693 		ret = ssd130x_write_data(ssd130x, data_array, width * pages);
694 
695 	return ret;
696 }
697 
698 static int ssd132x_update_rect(struct ssd130x_device *ssd130x,
699 			       struct drm_rect *rect, u8 *buf,
700 			       u8 *data_array)
701 {
702 	unsigned int x = rect->x1;
703 	unsigned int y = rect->y1;
704 	unsigned int segment_width = SSD132X_SEGMENT_WIDTH;
705 	unsigned int width = drm_rect_width(rect);
706 	unsigned int height = drm_rect_height(rect);
707 	unsigned int columns = DIV_ROUND_UP(width, segment_width);
708 	unsigned int rows = height;
709 	struct drm_device *drm = &ssd130x->drm;
710 	u32 array_idx = 0;
711 	unsigned int i, j;
712 	int ret;
713 
714 	drm_WARN_ONCE(drm, x % segment_width != 0, "x must be aligned to screen segment\n");
715 
716 	/*
717 	 * The screen is divided in Segment and Common outputs, where
718 	 * COM0 to COM[N - 1] are the rows and SEG0 to SEG[M - 1] are
719 	 * the columns.
720 	 *
721 	 * Each Segment has a 4-bit pixel and each Common output has a
722 	 * row of pixels. When using the (default) horizontal address
723 	 * increment mode, each byte of data sent to the controller has
724 	 * two Segments (e.g: SEG0 and SEG1) that are stored in the lower
725 	 * and higher nibbles of a single byte representing one column.
726 	 * That is, the first byte are SEG0 (D0[3:0]) and SEG1 (D0[7:4]),
727 	 * the second byte are SEG2 (D1[3:0]) and SEG3 (D1[7:4]) and so on.
728 	 */
729 
730 	/* Set column start and end */
731 	ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_COL_RANGE, x / segment_width, columns - 1);
732 	if (ret < 0)
733 		return ret;
734 
735 	/* Set row start and end */
736 	ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_ROW_RANGE, y, rows - 1);
737 	if (ret < 0)
738 		return ret;
739 
740 	for (i = 0; i < height; i++) {
741 		/* Process pair of pixels and combine them into a single byte */
742 		for (j = 0; j < width; j += segment_width) {
743 			u8 n1 = buf[i * width + j];
744 			u8 n2 = buf[i * width + j + 1];
745 
746 			data_array[array_idx++] = (n2 << 4) | n1;
747 		}
748 	}
749 
750 	/* Write out update in one go since horizontal addressing mode is used */
751 	ret = ssd130x_write_data(ssd130x, data_array, columns * rows);
752 
753 	return ret;
754 }
755 
756 static void ssd130x_clear_screen(struct ssd130x_device *ssd130x, u8 *data_array)
757 {
758 	unsigned int pages = DIV_ROUND_UP(ssd130x->height, SSD130X_PAGE_HEIGHT);
759 	unsigned int width = ssd130x->width;
760 	int ret, i;
761 
762 	if (!ssd130x->page_address_mode) {
763 		memset(data_array, 0, width * pages);
764 
765 		/* Set address range for horizontal addressing mode */
766 		ret = ssd130x_set_col_range(ssd130x, ssd130x->col_offset, width);
767 		if (ret < 0)
768 			return;
769 
770 		ret = ssd130x_set_page_range(ssd130x, ssd130x->page_offset, pages);
771 		if (ret < 0)
772 			return;
773 
774 		/* Write out update in one go if we aren't using page addressing mode */
775 		ssd130x_write_data(ssd130x, data_array, width * pages);
776 	} else {
777 		/*
778 		 * In page addressing mode, the start address needs to be reset,
779 		 * and each page then needs to be written out separately.
780 		 */
781 		memset(data_array, 0, width);
782 
783 		for (i = 0; i < pages; i++) {
784 			ret = ssd130x_set_page_pos(ssd130x,
785 						   ssd130x->page_offset + i,
786 						   ssd130x->col_offset);
787 			if (ret < 0)
788 				return;
789 
790 			ret = ssd130x_write_data(ssd130x, data_array, width);
791 			if (ret < 0)
792 				return;
793 		}
794 	}
795 }
796 
797 static void ssd132x_clear_screen(struct ssd130x_device *ssd130x, u8 *data_array)
798 {
799 	unsigned int columns = DIV_ROUND_UP(ssd130x->height, SSD132X_SEGMENT_WIDTH);
800 	unsigned int height = ssd130x->height;
801 
802 	memset(data_array, 0, columns * height);
803 
804 	/* Write out update in one go since horizontal addressing mode is used */
805 	ssd130x_write_data(ssd130x, data_array, columns * height);
806 }
807 
808 static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb,
809 				const struct iosys_map *vmap,
810 				struct drm_rect *rect,
811 				u8 *buf, u8 *data_array,
812 				struct drm_format_conv_state *fmtcnv_state)
813 {
814 	struct ssd130x_device *ssd130x = drm_to_ssd130x(fb->dev);
815 	struct iosys_map dst;
816 	unsigned int dst_pitch;
817 	int ret = 0;
818 
819 	/* Align y to display page boundaries */
820 	rect->y1 = round_down(rect->y1, SSD130X_PAGE_HEIGHT);
821 	rect->y2 = min_t(unsigned int, round_up(rect->y2, SSD130X_PAGE_HEIGHT), ssd130x->height);
822 
823 	dst_pitch = DIV_ROUND_UP(drm_rect_width(rect), 8);
824 
825 	ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE);
826 	if (ret)
827 		return ret;
828 
829 	iosys_map_set_vaddr(&dst, buf);
830 	drm_fb_xrgb8888_to_mono(&dst, &dst_pitch, vmap, fb, rect, fmtcnv_state);
831 
832 	drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
833 
834 	ssd130x_update_rect(ssd130x, rect, buf, data_array);
835 
836 	return ret;
837 }
838 
839 static int ssd132x_fb_blit_rect(struct drm_framebuffer *fb,
840 				const struct iosys_map *vmap,
841 				struct drm_rect *rect, u8 *buf,
842 				u8 *data_array,
843 				struct drm_format_conv_state *fmtcnv_state)
844 {
845 	struct ssd130x_device *ssd130x = drm_to_ssd130x(fb->dev);
846 	unsigned int dst_pitch = drm_rect_width(rect);
847 	struct iosys_map dst;
848 	int ret = 0;
849 
850 	/* Align x to display segment boundaries */
851 	rect->x1 = round_down(rect->x1, SSD132X_SEGMENT_WIDTH);
852 	rect->x2 = min_t(unsigned int, round_up(rect->x2, SSD132X_SEGMENT_WIDTH),
853 			 ssd130x->width);
854 
855 	ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE);
856 	if (ret)
857 		return ret;
858 
859 	iosys_map_set_vaddr(&dst, buf);
860 	drm_fb_xrgb8888_to_gray8(&dst, &dst_pitch, vmap, fb, rect, fmtcnv_state);
861 
862 	drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
863 
864 	ssd132x_update_rect(ssd130x, rect, buf, data_array);
865 
866 	return ret;
867 }
868 
869 static int ssd130x_primary_plane_atomic_check(struct drm_plane *plane,
870 					      struct drm_atomic_state *state)
871 {
872 	struct drm_device *drm = plane->dev;
873 	struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
874 	struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
875 	struct ssd130x_plane_state *ssd130x_state = to_ssd130x_plane_state(plane_state);
876 	struct drm_shadow_plane_state *shadow_plane_state = &ssd130x_state->base;
877 	struct drm_crtc *crtc = plane_state->crtc;
878 	struct drm_crtc_state *crtc_state = NULL;
879 	const struct drm_format_info *fi;
880 	unsigned int pitch;
881 	int ret;
882 
883 	if (crtc)
884 		crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
885 
886 	ret = drm_atomic_helper_check_plane_state(plane_state, crtc_state,
887 						  DRM_PLANE_NO_SCALING,
888 						  DRM_PLANE_NO_SCALING,
889 						  false, false);
890 	if (ret)
891 		return ret;
892 	else if (!plane_state->visible)
893 		return 0;
894 
895 	fi = drm_format_info(DRM_FORMAT_R1);
896 	if (!fi)
897 		return -EINVAL;
898 
899 	pitch = drm_format_info_min_pitch(fi, 0, ssd130x->width);
900 
901 	if (plane_state->fb->format != fi) {
902 		void *buf;
903 
904 		/* format conversion necessary; reserve buffer */
905 		buf = drm_format_conv_state_reserve(&shadow_plane_state->fmtcnv_state,
906 						    pitch, GFP_KERNEL);
907 		if (!buf)
908 			return -ENOMEM;
909 	}
910 
911 	ssd130x_state->buffer = kcalloc(pitch, ssd130x->height, GFP_KERNEL);
912 	if (!ssd130x_state->buffer)
913 		return -ENOMEM;
914 
915 	return 0;
916 }
917 
918 static int ssd132x_primary_plane_atomic_check(struct drm_plane *plane,
919 					      struct drm_atomic_state *state)
920 {
921 	struct drm_device *drm = plane->dev;
922 	struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
923 	struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
924 	struct ssd130x_plane_state *ssd130x_state = to_ssd130x_plane_state(plane_state);
925 	struct drm_shadow_plane_state *shadow_plane_state = &ssd130x_state->base;
926 	struct drm_crtc *crtc = plane_state->crtc;
927 	struct drm_crtc_state *crtc_state = NULL;
928 	const struct drm_format_info *fi;
929 	unsigned int pitch;
930 	int ret;
931 
932 	if (crtc)
933 		crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
934 
935 	ret = drm_atomic_helper_check_plane_state(plane_state, crtc_state,
936 						  DRM_PLANE_NO_SCALING,
937 						  DRM_PLANE_NO_SCALING,
938 						  false, false);
939 	if (ret)
940 		return ret;
941 	else if (!plane_state->visible)
942 		return 0;
943 
944 	fi = drm_format_info(DRM_FORMAT_R8);
945 	if (!fi)
946 		return -EINVAL;
947 
948 	pitch = drm_format_info_min_pitch(fi, 0, ssd130x->width);
949 
950 	if (plane_state->fb->format != fi) {
951 		void *buf;
952 
953 		/* format conversion necessary; reserve buffer */
954 		buf = drm_format_conv_state_reserve(&shadow_plane_state->fmtcnv_state,
955 						    pitch, GFP_KERNEL);
956 		if (!buf)
957 			return -ENOMEM;
958 	}
959 
960 	ssd130x_state->buffer = kcalloc(pitch, ssd130x->height, GFP_KERNEL);
961 	if (!ssd130x_state->buffer)
962 		return -ENOMEM;
963 
964 	return 0;
965 }
966 
967 static void ssd130x_primary_plane_atomic_update(struct drm_plane *plane,
968 						struct drm_atomic_state *state)
969 {
970 	struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
971 	struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
972 	struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
973 	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, plane_state->crtc);
974 	struct ssd130x_crtc_state *ssd130x_crtc_state =  to_ssd130x_crtc_state(crtc_state);
975 	struct ssd130x_plane_state *ssd130x_plane_state = to_ssd130x_plane_state(plane_state);
976 	struct drm_framebuffer *fb = plane_state->fb;
977 	struct drm_atomic_helper_damage_iter iter;
978 	struct drm_device *drm = plane->dev;
979 	struct drm_rect dst_clip;
980 	struct drm_rect damage;
981 	int idx;
982 
983 	if (!drm_dev_enter(drm, &idx))
984 		return;
985 
986 	drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state);
987 	drm_atomic_for_each_plane_damage(&iter, &damage) {
988 		dst_clip = plane_state->dst;
989 
990 		if (!drm_rect_intersect(&dst_clip, &damage))
991 			continue;
992 
993 		ssd130x_fb_blit_rect(fb, &shadow_plane_state->data[0], &dst_clip,
994 				     ssd130x_plane_state->buffer,
995 				     ssd130x_crtc_state->data_array,
996 				     &shadow_plane_state->fmtcnv_state);
997 	}
998 
999 	drm_dev_exit(idx);
1000 }
1001 
1002 static void ssd132x_primary_plane_atomic_update(struct drm_plane *plane,
1003 						struct drm_atomic_state *state)
1004 {
1005 	struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
1006 	struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
1007 	struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
1008 	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, plane_state->crtc);
1009 	struct ssd130x_crtc_state *ssd130x_crtc_state =  to_ssd130x_crtc_state(crtc_state);
1010 	struct ssd130x_plane_state *ssd130x_plane_state = to_ssd130x_plane_state(plane_state);
1011 	struct drm_framebuffer *fb = plane_state->fb;
1012 	struct drm_atomic_helper_damage_iter iter;
1013 	struct drm_device *drm = plane->dev;
1014 	struct drm_rect dst_clip;
1015 	struct drm_rect damage;
1016 	int idx;
1017 
1018 	if (!drm_dev_enter(drm, &idx))
1019 		return;
1020 
1021 	drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state);
1022 	drm_atomic_for_each_plane_damage(&iter, &damage) {
1023 		dst_clip = plane_state->dst;
1024 
1025 		if (!drm_rect_intersect(&dst_clip, &damage))
1026 			continue;
1027 
1028 		ssd132x_fb_blit_rect(fb, &shadow_plane_state->data[0], &dst_clip,
1029 				     ssd130x_plane_state->buffer,
1030 				     ssd130x_crtc_state->data_array,
1031 				     &shadow_plane_state->fmtcnv_state);
1032 	}
1033 
1034 	drm_dev_exit(idx);
1035 }
1036 
1037 static void ssd130x_primary_plane_atomic_disable(struct drm_plane *plane,
1038 						 struct drm_atomic_state *state)
1039 {
1040 	struct drm_device *drm = plane->dev;
1041 	struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
1042 	struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
1043 	struct drm_crtc_state *crtc_state;
1044 	struct ssd130x_crtc_state *ssd130x_crtc_state;
1045 	int idx;
1046 
1047 	if (!plane_state->crtc)
1048 		return;
1049 
1050 	crtc_state = drm_atomic_get_new_crtc_state(state, plane_state->crtc);
1051 	ssd130x_crtc_state = to_ssd130x_crtc_state(crtc_state);
1052 
1053 	if (!drm_dev_enter(drm, &idx))
1054 		return;
1055 
1056 	ssd130x_clear_screen(ssd130x, ssd130x_crtc_state->data_array);
1057 
1058 	drm_dev_exit(idx);
1059 }
1060 
1061 static void ssd132x_primary_plane_atomic_disable(struct drm_plane *plane,
1062 						 struct drm_atomic_state *state)
1063 {
1064 	struct drm_device *drm = plane->dev;
1065 	struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
1066 	struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
1067 	struct drm_crtc_state *crtc_state;
1068 	struct ssd130x_crtc_state *ssd130x_crtc_state;
1069 	int idx;
1070 
1071 	if (!plane_state->crtc)
1072 		return;
1073 
1074 	crtc_state = drm_atomic_get_new_crtc_state(state, plane_state->crtc);
1075 	ssd130x_crtc_state = to_ssd130x_crtc_state(crtc_state);
1076 
1077 	if (!drm_dev_enter(drm, &idx))
1078 		return;
1079 
1080 	ssd132x_clear_screen(ssd130x, ssd130x_crtc_state->data_array);
1081 
1082 	drm_dev_exit(idx);
1083 }
1084 
1085 /* Called during init to allocate the plane's atomic state. */
1086 static void ssd130x_primary_plane_reset(struct drm_plane *plane)
1087 {
1088 	struct ssd130x_plane_state *ssd130x_state;
1089 
1090 	WARN_ON(plane->state);
1091 
1092 	ssd130x_state = kzalloc(sizeof(*ssd130x_state), GFP_KERNEL);
1093 	if (!ssd130x_state)
1094 		return;
1095 
1096 	__drm_gem_reset_shadow_plane(plane, &ssd130x_state->base);
1097 }
1098 
1099 static struct drm_plane_state *ssd130x_primary_plane_duplicate_state(struct drm_plane *plane)
1100 {
1101 	struct drm_shadow_plane_state *new_shadow_plane_state;
1102 	struct ssd130x_plane_state *old_ssd130x_state;
1103 	struct ssd130x_plane_state *ssd130x_state;
1104 
1105 	if (WARN_ON(!plane->state))
1106 		return NULL;
1107 
1108 	old_ssd130x_state = to_ssd130x_plane_state(plane->state);
1109 	ssd130x_state = kmemdup(old_ssd130x_state, sizeof(*ssd130x_state), GFP_KERNEL);
1110 	if (!ssd130x_state)
1111 		return NULL;
1112 
1113 	/* The buffer is not duplicated and is allocated in .atomic_check */
1114 	ssd130x_state->buffer = NULL;
1115 
1116 	new_shadow_plane_state = &ssd130x_state->base;
1117 
1118 	__drm_gem_duplicate_shadow_plane_state(plane, new_shadow_plane_state);
1119 
1120 	return &new_shadow_plane_state->base;
1121 }
1122 
1123 static void ssd130x_primary_plane_destroy_state(struct drm_plane *plane,
1124 						struct drm_plane_state *state)
1125 {
1126 	struct ssd130x_plane_state *ssd130x_state = to_ssd130x_plane_state(state);
1127 
1128 	kfree(ssd130x_state->buffer);
1129 
1130 	__drm_gem_destroy_shadow_plane_state(&ssd130x_state->base);
1131 
1132 	kfree(ssd130x_state);
1133 }
1134 
1135 static const struct drm_plane_helper_funcs ssd130x_primary_plane_helper_funcs[] = {
1136 	[SSD130X_FAMILY] = {
1137 		DRM_GEM_SHADOW_PLANE_HELPER_FUNCS,
1138 		.atomic_check = ssd130x_primary_plane_atomic_check,
1139 		.atomic_update = ssd130x_primary_plane_atomic_update,
1140 		.atomic_disable = ssd130x_primary_plane_atomic_disable,
1141 	},
1142 	[SSD132X_FAMILY] = {
1143 		DRM_GEM_SHADOW_PLANE_HELPER_FUNCS,
1144 		.atomic_check = ssd132x_primary_plane_atomic_check,
1145 		.atomic_update = ssd132x_primary_plane_atomic_update,
1146 		.atomic_disable = ssd132x_primary_plane_atomic_disable,
1147 	}
1148 };
1149 
1150 static const struct drm_plane_funcs ssd130x_primary_plane_funcs = {
1151 	.update_plane = drm_atomic_helper_update_plane,
1152 	.disable_plane = drm_atomic_helper_disable_plane,
1153 	.reset = ssd130x_primary_plane_reset,
1154 	.atomic_duplicate_state = ssd130x_primary_plane_duplicate_state,
1155 	.atomic_destroy_state = ssd130x_primary_plane_destroy_state,
1156 	.destroy = drm_plane_cleanup,
1157 };
1158 
1159 static enum drm_mode_status ssd130x_crtc_mode_valid(struct drm_crtc *crtc,
1160 						    const struct drm_display_mode *mode)
1161 {
1162 	struct ssd130x_device *ssd130x = drm_to_ssd130x(crtc->dev);
1163 
1164 	if (mode->hdisplay != ssd130x->mode.hdisplay &&
1165 	    mode->vdisplay != ssd130x->mode.vdisplay)
1166 		return MODE_ONE_SIZE;
1167 	else if (mode->hdisplay != ssd130x->mode.hdisplay)
1168 		return MODE_ONE_WIDTH;
1169 	else if (mode->vdisplay != ssd130x->mode.vdisplay)
1170 		return MODE_ONE_HEIGHT;
1171 
1172 	return MODE_OK;
1173 }
1174 
1175 static int ssd130x_crtc_atomic_check(struct drm_crtc *crtc,
1176 				     struct drm_atomic_state *state)
1177 {
1178 	struct drm_device *drm = crtc->dev;
1179 	struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
1180 	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
1181 	struct ssd130x_crtc_state *ssd130x_state = to_ssd130x_crtc_state(crtc_state);
1182 	unsigned int pages = DIV_ROUND_UP(ssd130x->height, SSD130X_PAGE_HEIGHT);
1183 	int ret;
1184 
1185 	ret = drm_crtc_helper_atomic_check(crtc, state);
1186 	if (ret)
1187 		return ret;
1188 
1189 	ssd130x_state->data_array = kmalloc(ssd130x->width * pages, GFP_KERNEL);
1190 	if (!ssd130x_state->data_array)
1191 		return -ENOMEM;
1192 
1193 	return 0;
1194 }
1195 
1196 static int ssd132x_crtc_atomic_check(struct drm_crtc *crtc,
1197 				     struct drm_atomic_state *state)
1198 {
1199 	struct drm_device *drm = crtc->dev;
1200 	struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
1201 	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
1202 	struct ssd130x_crtc_state *ssd130x_state = to_ssd130x_crtc_state(crtc_state);
1203 	unsigned int columns = DIV_ROUND_UP(ssd130x->width, SSD132X_SEGMENT_WIDTH);
1204 	int ret;
1205 
1206 	ret = drm_crtc_helper_atomic_check(crtc, state);
1207 	if (ret)
1208 		return ret;
1209 
1210 	ssd130x_state->data_array = kmalloc(columns * ssd130x->height, GFP_KERNEL);
1211 	if (!ssd130x_state->data_array)
1212 		return -ENOMEM;
1213 
1214 	return 0;
1215 }
1216 
1217 /* Called during init to allocate the CRTC's atomic state. */
1218 static void ssd130x_crtc_reset(struct drm_crtc *crtc)
1219 {
1220 	struct ssd130x_crtc_state *ssd130x_state;
1221 
1222 	WARN_ON(crtc->state);
1223 
1224 	ssd130x_state = kzalloc(sizeof(*ssd130x_state), GFP_KERNEL);
1225 	if (!ssd130x_state)
1226 		return;
1227 
1228 	__drm_atomic_helper_crtc_reset(crtc, &ssd130x_state->base);
1229 }
1230 
1231 static struct drm_crtc_state *ssd130x_crtc_duplicate_state(struct drm_crtc *crtc)
1232 {
1233 	struct ssd130x_crtc_state *old_ssd130x_state;
1234 	struct ssd130x_crtc_state *ssd130x_state;
1235 
1236 	if (WARN_ON(!crtc->state))
1237 		return NULL;
1238 
1239 	old_ssd130x_state = to_ssd130x_crtc_state(crtc->state);
1240 	ssd130x_state = kmemdup(old_ssd130x_state, sizeof(*ssd130x_state), GFP_KERNEL);
1241 	if (!ssd130x_state)
1242 		return NULL;
1243 
1244 	/* The buffer is not duplicated and is allocated in .atomic_check */
1245 	ssd130x_state->data_array = NULL;
1246 
1247 	__drm_atomic_helper_crtc_duplicate_state(crtc, &ssd130x_state->base);
1248 
1249 	return &ssd130x_state->base;
1250 }
1251 
1252 static void ssd130x_crtc_destroy_state(struct drm_crtc *crtc,
1253 				       struct drm_crtc_state *state)
1254 {
1255 	struct ssd130x_crtc_state *ssd130x_state = to_ssd130x_crtc_state(state);
1256 
1257 	kfree(ssd130x_state->data_array);
1258 
1259 	__drm_atomic_helper_crtc_destroy_state(state);
1260 
1261 	kfree(ssd130x_state);
1262 }
1263 
1264 /*
1265  * The CRTC is always enabled. Screen updates are performed by
1266  * the primary plane's atomic_update function. Disabling clears
1267  * the screen in the primary plane's atomic_disable function.
1268  */
1269 static const struct drm_crtc_helper_funcs ssd130x_crtc_helper_funcs[] = {
1270 	[SSD130X_FAMILY] = {
1271 		.mode_valid = ssd130x_crtc_mode_valid,
1272 		.atomic_check = ssd130x_crtc_atomic_check,
1273 	},
1274 	[SSD132X_FAMILY] = {
1275 		.mode_valid = ssd130x_crtc_mode_valid,
1276 		.atomic_check = ssd132x_crtc_atomic_check,
1277 	},
1278 };
1279 
1280 static const struct drm_crtc_funcs ssd130x_crtc_funcs = {
1281 	.reset = ssd130x_crtc_reset,
1282 	.destroy = drm_crtc_cleanup,
1283 	.set_config = drm_atomic_helper_set_config,
1284 	.page_flip = drm_atomic_helper_page_flip,
1285 	.atomic_duplicate_state = ssd130x_crtc_duplicate_state,
1286 	.atomic_destroy_state = ssd130x_crtc_destroy_state,
1287 };
1288 
1289 static void ssd130x_encoder_atomic_enable(struct drm_encoder *encoder,
1290 					  struct drm_atomic_state *state)
1291 {
1292 	struct drm_device *drm = encoder->dev;
1293 	struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
1294 	int ret;
1295 
1296 	ret = ssd130x_power_on(ssd130x);
1297 	if (ret)
1298 		return;
1299 
1300 	ret = ssd130x_init(ssd130x);
1301 	if (ret)
1302 		goto power_off;
1303 
1304 	ssd130x_write_cmd(ssd130x, 1, SSD13XX_DISPLAY_ON);
1305 
1306 	backlight_enable(ssd130x->bl_dev);
1307 
1308 	return;
1309 
1310 power_off:
1311 	ssd130x_power_off(ssd130x);
1312 	return;
1313 }
1314 
1315 static void ssd132x_encoder_atomic_enable(struct drm_encoder *encoder,
1316 					  struct drm_atomic_state *state)
1317 {
1318 	struct drm_device *drm = encoder->dev;
1319 	struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
1320 	int ret;
1321 
1322 	ret = ssd130x_power_on(ssd130x);
1323 	if (ret)
1324 		return;
1325 
1326 	ret = ssd132x_init(ssd130x);
1327 	if (ret)
1328 		goto power_off;
1329 
1330 	ssd130x_write_cmd(ssd130x, 1, SSD13XX_DISPLAY_ON);
1331 
1332 	backlight_enable(ssd130x->bl_dev);
1333 
1334 	return;
1335 
1336 power_off:
1337 	ssd130x_power_off(ssd130x);
1338 }
1339 
1340 static void ssd130x_encoder_atomic_disable(struct drm_encoder *encoder,
1341 					   struct drm_atomic_state *state)
1342 {
1343 	struct drm_device *drm = encoder->dev;
1344 	struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
1345 
1346 	backlight_disable(ssd130x->bl_dev);
1347 
1348 	ssd130x_write_cmd(ssd130x, 1, SSD13XX_DISPLAY_OFF);
1349 
1350 	ssd130x_power_off(ssd130x);
1351 }
1352 
1353 static const struct drm_encoder_helper_funcs ssd130x_encoder_helper_funcs[] = {
1354 	[SSD130X_FAMILY] = {
1355 		.atomic_enable = ssd130x_encoder_atomic_enable,
1356 		.atomic_disable = ssd130x_encoder_atomic_disable,
1357 	},
1358 	[SSD132X_FAMILY] = {
1359 		.atomic_enable = ssd132x_encoder_atomic_enable,
1360 		.atomic_disable = ssd130x_encoder_atomic_disable,
1361 	}
1362 };
1363 
1364 static const struct drm_encoder_funcs ssd130x_encoder_funcs = {
1365 	.destroy = drm_encoder_cleanup,
1366 };
1367 
1368 static int ssd130x_connector_get_modes(struct drm_connector *connector)
1369 {
1370 	struct ssd130x_device *ssd130x = drm_to_ssd130x(connector->dev);
1371 	struct drm_display_mode *mode;
1372 	struct device *dev = ssd130x->dev;
1373 
1374 	mode = drm_mode_duplicate(connector->dev, &ssd130x->mode);
1375 	if (!mode) {
1376 		dev_err(dev, "Failed to duplicated mode\n");
1377 		return 0;
1378 	}
1379 
1380 	drm_mode_probed_add(connector, mode);
1381 	drm_set_preferred_mode(connector, mode->hdisplay, mode->vdisplay);
1382 
1383 	/* There is only a single mode */
1384 	return 1;
1385 }
1386 
1387 static const struct drm_connector_helper_funcs ssd130x_connector_helper_funcs = {
1388 	.get_modes = ssd130x_connector_get_modes,
1389 };
1390 
1391 static const struct drm_connector_funcs ssd130x_connector_funcs = {
1392 	.reset = drm_atomic_helper_connector_reset,
1393 	.fill_modes = drm_helper_probe_single_connector_modes,
1394 	.destroy = drm_connector_cleanup,
1395 	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
1396 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
1397 };
1398 
1399 static const struct drm_mode_config_funcs ssd130x_mode_config_funcs = {
1400 	.fb_create = drm_gem_fb_create_with_dirty,
1401 	.atomic_check = drm_atomic_helper_check,
1402 	.atomic_commit = drm_atomic_helper_commit,
1403 };
1404 
1405 static const uint32_t ssd130x_formats[] = {
1406 	DRM_FORMAT_XRGB8888,
1407 };
1408 
1409 DEFINE_DRM_GEM_FOPS(ssd130x_fops);
1410 
1411 static const struct drm_driver ssd130x_drm_driver = {
1412 	DRM_GEM_SHMEM_DRIVER_OPS,
1413 	.name			= DRIVER_NAME,
1414 	.desc			= DRIVER_DESC,
1415 	.date			= DRIVER_DATE,
1416 	.major			= DRIVER_MAJOR,
1417 	.minor			= DRIVER_MINOR,
1418 	.driver_features	= DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
1419 	.fops			= &ssd130x_fops,
1420 };
1421 
1422 static int ssd130x_update_bl(struct backlight_device *bdev)
1423 {
1424 	struct ssd130x_device *ssd130x = bl_get_data(bdev);
1425 	int brightness = backlight_get_brightness(bdev);
1426 	int ret;
1427 
1428 	ssd130x->contrast = brightness;
1429 
1430 	ret = ssd130x_write_cmd(ssd130x, 1, SSD13XX_CONTRAST);
1431 	if (ret < 0)
1432 		return ret;
1433 
1434 	ret = ssd130x_write_cmd(ssd130x, 1, ssd130x->contrast);
1435 	if (ret < 0)
1436 		return ret;
1437 
1438 	return 0;
1439 }
1440 
1441 static const struct backlight_ops ssd130xfb_bl_ops = {
1442 	.update_status	= ssd130x_update_bl,
1443 };
1444 
1445 static void ssd130x_parse_properties(struct ssd130x_device *ssd130x)
1446 {
1447 	struct device *dev = ssd130x->dev;
1448 
1449 	if (device_property_read_u32(dev, "solomon,width", &ssd130x->width))
1450 		ssd130x->width = ssd130x->device_info->default_width;
1451 
1452 	if (device_property_read_u32(dev, "solomon,height", &ssd130x->height))
1453 		ssd130x->height = ssd130x->device_info->default_height;
1454 
1455 	if (device_property_read_u32(dev, "solomon,page-offset", &ssd130x->page_offset))
1456 		ssd130x->page_offset = 1;
1457 
1458 	if (device_property_read_u32(dev, "solomon,col-offset", &ssd130x->col_offset))
1459 		ssd130x->col_offset = 0;
1460 
1461 	if (device_property_read_u32(dev, "solomon,com-offset", &ssd130x->com_offset))
1462 		ssd130x->com_offset = 0;
1463 
1464 	if (device_property_read_u32(dev, "solomon,prechargep1", &ssd130x->prechargep1))
1465 		ssd130x->prechargep1 = 2;
1466 
1467 	if (device_property_read_u32(dev, "solomon,prechargep2", &ssd130x->prechargep2))
1468 		ssd130x->prechargep2 = 2;
1469 
1470 	if (!device_property_read_u8_array(dev, "solomon,lookup-table",
1471 					   ssd130x->lookup_table,
1472 					   ARRAY_SIZE(ssd130x->lookup_table)))
1473 		ssd130x->lookup_table_set = 1;
1474 
1475 	ssd130x->seg_remap = !device_property_read_bool(dev, "solomon,segment-no-remap");
1476 	ssd130x->com_seq = device_property_read_bool(dev, "solomon,com-seq");
1477 	ssd130x->com_lrremap = device_property_read_bool(dev, "solomon,com-lrremap");
1478 	ssd130x->com_invdir = device_property_read_bool(dev, "solomon,com-invdir");
1479 	ssd130x->area_color_enable =
1480 		device_property_read_bool(dev, "solomon,area-color-enable");
1481 	ssd130x->low_power = device_property_read_bool(dev, "solomon,low-power");
1482 
1483 	ssd130x->contrast = 127;
1484 	ssd130x->vcomh = ssd130x->device_info->default_vcomh;
1485 
1486 	/* Setup display timing */
1487 	if (device_property_read_u32(dev, "solomon,dclk-div", &ssd130x->dclk_div))
1488 		ssd130x->dclk_div = ssd130x->device_info->default_dclk_div;
1489 	if (device_property_read_u32(dev, "solomon,dclk-frq", &ssd130x->dclk_frq))
1490 		ssd130x->dclk_frq = ssd130x->device_info->default_dclk_frq;
1491 }
1492 
1493 static int ssd130x_init_modeset(struct ssd130x_device *ssd130x)
1494 {
1495 	enum ssd130x_family_ids family_id = ssd130x->device_info->family_id;
1496 	struct drm_display_mode *mode = &ssd130x->mode;
1497 	struct device *dev = ssd130x->dev;
1498 	struct drm_device *drm = &ssd130x->drm;
1499 	unsigned long max_width, max_height;
1500 	struct drm_plane *primary_plane;
1501 	struct drm_crtc *crtc;
1502 	struct drm_encoder *encoder;
1503 	struct drm_connector *connector;
1504 	int ret;
1505 
1506 	/*
1507 	 * Modesetting
1508 	 */
1509 
1510 	ret = drmm_mode_config_init(drm);
1511 	if (ret) {
1512 		dev_err(dev, "DRM mode config init failed: %d\n", ret);
1513 		return ret;
1514 	}
1515 
1516 	mode->type = DRM_MODE_TYPE_DRIVER;
1517 	mode->clock = 1;
1518 	mode->hdisplay = mode->htotal = ssd130x->width;
1519 	mode->hsync_start = mode->hsync_end = ssd130x->width;
1520 	mode->vdisplay = mode->vtotal = ssd130x->height;
1521 	mode->vsync_start = mode->vsync_end = ssd130x->height;
1522 	mode->width_mm = 27;
1523 	mode->height_mm = 27;
1524 
1525 	max_width = max_t(unsigned long, mode->hdisplay, DRM_SHADOW_PLANE_MAX_WIDTH);
1526 	max_height = max_t(unsigned long, mode->vdisplay, DRM_SHADOW_PLANE_MAX_HEIGHT);
1527 
1528 	drm->mode_config.min_width = mode->hdisplay;
1529 	drm->mode_config.max_width = max_width;
1530 	drm->mode_config.min_height = mode->vdisplay;
1531 	drm->mode_config.max_height = max_height;
1532 	drm->mode_config.preferred_depth = 24;
1533 	drm->mode_config.funcs = &ssd130x_mode_config_funcs;
1534 
1535 	/* Primary plane */
1536 
1537 	primary_plane = &ssd130x->primary_plane;
1538 	ret = drm_universal_plane_init(drm, primary_plane, 0, &ssd130x_primary_plane_funcs,
1539 				       ssd130x_formats, ARRAY_SIZE(ssd130x_formats),
1540 				       NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
1541 	if (ret) {
1542 		dev_err(dev, "DRM primary plane init failed: %d\n", ret);
1543 		return ret;
1544 	}
1545 
1546 	drm_plane_helper_add(primary_plane, &ssd130x_primary_plane_helper_funcs[family_id]);
1547 
1548 	drm_plane_enable_fb_damage_clips(primary_plane);
1549 
1550 	/* CRTC */
1551 
1552 	crtc = &ssd130x->crtc;
1553 	ret = drm_crtc_init_with_planes(drm, crtc, primary_plane, NULL,
1554 					&ssd130x_crtc_funcs, NULL);
1555 	if (ret) {
1556 		dev_err(dev, "DRM crtc init failed: %d\n", ret);
1557 		return ret;
1558 	}
1559 
1560 	drm_crtc_helper_add(crtc, &ssd130x_crtc_helper_funcs[family_id]);
1561 
1562 	/* Encoder */
1563 
1564 	encoder = &ssd130x->encoder;
1565 	ret = drm_encoder_init(drm, encoder, &ssd130x_encoder_funcs,
1566 			       DRM_MODE_ENCODER_NONE, NULL);
1567 	if (ret) {
1568 		dev_err(dev, "DRM encoder init failed: %d\n", ret);
1569 		return ret;
1570 	}
1571 
1572 	drm_encoder_helper_add(encoder, &ssd130x_encoder_helper_funcs[family_id]);
1573 
1574 	encoder->possible_crtcs = drm_crtc_mask(crtc);
1575 
1576 	/* Connector */
1577 
1578 	connector = &ssd130x->connector;
1579 	ret = drm_connector_init(drm, connector, &ssd130x_connector_funcs,
1580 				 DRM_MODE_CONNECTOR_Unknown);
1581 	if (ret) {
1582 		dev_err(dev, "DRM connector init failed: %d\n", ret);
1583 		return ret;
1584 	}
1585 
1586 	drm_connector_helper_add(connector, &ssd130x_connector_helper_funcs);
1587 
1588 	ret = drm_connector_attach_encoder(connector, encoder);
1589 	if (ret) {
1590 		dev_err(dev, "DRM attach connector to encoder failed: %d\n", ret);
1591 		return ret;
1592 	}
1593 
1594 	drm_mode_config_reset(drm);
1595 
1596 	return 0;
1597 }
1598 
1599 static int ssd130x_get_resources(struct ssd130x_device *ssd130x)
1600 {
1601 	struct device *dev = ssd130x->dev;
1602 
1603 	ssd130x->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
1604 	if (IS_ERR(ssd130x->reset))
1605 		return dev_err_probe(dev, PTR_ERR(ssd130x->reset),
1606 				     "Failed to get reset gpio\n");
1607 
1608 	ssd130x->vcc_reg = devm_regulator_get(dev, "vcc");
1609 	if (IS_ERR(ssd130x->vcc_reg))
1610 		return dev_err_probe(dev, PTR_ERR(ssd130x->vcc_reg),
1611 				     "Failed to get VCC regulator\n");
1612 
1613 	return 0;
1614 }
1615 
1616 struct ssd130x_device *ssd130x_probe(struct device *dev, struct regmap *regmap)
1617 {
1618 	struct ssd130x_device *ssd130x;
1619 	struct backlight_device *bl;
1620 	struct drm_device *drm;
1621 	int ret;
1622 
1623 	ssd130x = devm_drm_dev_alloc(dev, &ssd130x_drm_driver,
1624 				     struct ssd130x_device, drm);
1625 	if (IS_ERR(ssd130x))
1626 		return ERR_PTR(dev_err_probe(dev, PTR_ERR(ssd130x),
1627 					     "Failed to allocate DRM device\n"));
1628 
1629 	drm = &ssd130x->drm;
1630 
1631 	ssd130x->dev = dev;
1632 	ssd130x->regmap = regmap;
1633 	ssd130x->device_info = device_get_match_data(dev);
1634 
1635 	if (ssd130x->device_info->page_mode_only)
1636 		ssd130x->page_address_mode = 1;
1637 
1638 	ssd130x_parse_properties(ssd130x);
1639 
1640 	ret = ssd130x_get_resources(ssd130x);
1641 	if (ret)
1642 		return ERR_PTR(ret);
1643 
1644 	bl = devm_backlight_device_register(dev, dev_name(dev), dev, ssd130x,
1645 					    &ssd130xfb_bl_ops, NULL);
1646 	if (IS_ERR(bl))
1647 		return ERR_PTR(dev_err_probe(dev, PTR_ERR(bl),
1648 					     "Unable to register backlight device\n"));
1649 
1650 	bl->props.brightness = ssd130x->contrast;
1651 	bl->props.max_brightness = MAX_CONTRAST;
1652 	ssd130x->bl_dev = bl;
1653 
1654 	ret = ssd130x_init_modeset(ssd130x);
1655 	if (ret)
1656 		return ERR_PTR(ret);
1657 
1658 	ret = drm_dev_register(drm, 0);
1659 	if (ret)
1660 		return ERR_PTR(dev_err_probe(dev, ret, "DRM device register failed\n"));
1661 
1662 	drm_fbdev_generic_setup(drm, 32);
1663 
1664 	return ssd130x;
1665 }
1666 EXPORT_SYMBOL_GPL(ssd130x_probe);
1667 
1668 void ssd130x_remove(struct ssd130x_device *ssd130x)
1669 {
1670 	drm_dev_unplug(&ssd130x->drm);
1671 	drm_atomic_helper_shutdown(&ssd130x->drm);
1672 }
1673 EXPORT_SYMBOL_GPL(ssd130x_remove);
1674 
1675 void ssd130x_shutdown(struct ssd130x_device *ssd130x)
1676 {
1677 	drm_atomic_helper_shutdown(&ssd130x->drm);
1678 }
1679 EXPORT_SYMBOL_GPL(ssd130x_shutdown);
1680 
1681 MODULE_DESCRIPTION(DRIVER_DESC);
1682 MODULE_AUTHOR("Javier Martinez Canillas <javierm@redhat.com>");
1683 MODULE_LICENSE("GPL v2");
1684