1 /* 2 * Driver for the Himax HX-8357 LCD Controller 3 * 4 * Copyright 2012 Free Electrons 5 * 6 * Licensed under the GPLv2 or later. 7 */ 8 9 #include <linux/delay.h> 10 #include <linux/lcd.h> 11 #include <linux/module.h> 12 #include <linux/of.h> 13 #include <linux/of_device.h> 14 #include <linux/of_gpio.h> 15 #include <linux/spi/spi.h> 16 17 #define HX8357_NUM_IM_PINS 3 18 19 #define HX8357_SWRESET 0x01 20 #define HX8357_GET_RED_CHANNEL 0x06 21 #define HX8357_GET_GREEN_CHANNEL 0x07 22 #define HX8357_GET_BLUE_CHANNEL 0x08 23 #define HX8357_GET_POWER_MODE 0x0a 24 #define HX8357_GET_MADCTL 0x0b 25 #define HX8357_GET_PIXEL_FORMAT 0x0c 26 #define HX8357_GET_DISPLAY_MODE 0x0d 27 #define HX8357_GET_SIGNAL_MODE 0x0e 28 #define HX8357_GET_DIAGNOSTIC_RESULT 0x0f 29 #define HX8357_ENTER_SLEEP_MODE 0x10 30 #define HX8357_EXIT_SLEEP_MODE 0x11 31 #define HX8357_ENTER_PARTIAL_MODE 0x12 32 #define HX8357_ENTER_NORMAL_MODE 0x13 33 #define HX8357_EXIT_INVERSION_MODE 0x20 34 #define HX8357_ENTER_INVERSION_MODE 0x21 35 #define HX8357_SET_DISPLAY_OFF 0x28 36 #define HX8357_SET_DISPLAY_ON 0x29 37 #define HX8357_SET_COLUMN_ADDRESS 0x2a 38 #define HX8357_SET_PAGE_ADDRESS 0x2b 39 #define HX8357_WRITE_MEMORY_START 0x2c 40 #define HX8357_READ_MEMORY_START 0x2e 41 #define HX8357_SET_PARTIAL_AREA 0x30 42 #define HX8357_SET_SCROLL_AREA 0x33 43 #define HX8357_SET_TEAR_OFF 0x34 44 #define HX8357_SET_TEAR_ON 0x35 45 #define HX8357_SET_ADDRESS_MODE 0x36 46 #define HX8357_SET_SCROLL_START 0x37 47 #define HX8357_EXIT_IDLE_MODE 0x38 48 #define HX8357_ENTER_IDLE_MODE 0x39 49 #define HX8357_SET_PIXEL_FORMAT 0x3a 50 #define HX8357_SET_PIXEL_FORMAT_DBI_3BIT (0x1) 51 #define HX8357_SET_PIXEL_FORMAT_DBI_16BIT (0x5) 52 #define HX8357_SET_PIXEL_FORMAT_DBI_18BIT (0x6) 53 #define HX8357_SET_PIXEL_FORMAT_DPI_3BIT (0x1 << 4) 54 #define HX8357_SET_PIXEL_FORMAT_DPI_16BIT (0x5 << 4) 55 #define HX8357_SET_PIXEL_FORMAT_DPI_18BIT (0x6 << 4) 56 #define HX8357_WRITE_MEMORY_CONTINUE 0x3c 57 #define HX8357_READ_MEMORY_CONTINUE 0x3e 58 #define HX8357_SET_TEAR_SCAN_LINES 0x44 59 #define HX8357_GET_SCAN_LINES 0x45 60 #define HX8357_READ_DDB_START 0xa1 61 #define HX8357_SET_DISPLAY_MODE 0xb4 62 #define HX8357_SET_DISPLAY_MODE_RGB_THROUGH (0x3) 63 #define HX8357_SET_DISPLAY_MODE_RGB_INTERFACE (1 << 4) 64 #define HX8357_SET_PANEL_DRIVING 0xc0 65 #define HX8357_SET_DISPLAY_FRAME 0xc5 66 #define HX8357_SET_RGB 0xc6 67 #define HX8357_SET_RGB_ENABLE_HIGH (1 << 1) 68 #define HX8357_SET_GAMMA 0xc8 69 #define HX8357_SET_POWER 0xd0 70 #define HX8357_SET_VCOM 0xd1 71 #define HX8357_SET_POWER_NORMAL 0xd2 72 #define HX8357_SET_PANEL_RELATED 0xe9 73 74 struct hx8357_data { 75 unsigned im_pins[HX8357_NUM_IM_PINS]; 76 unsigned reset; 77 struct spi_device *spi; 78 int state; 79 }; 80 81 static u8 hx8357_seq_power[] = { 82 HX8357_SET_POWER, 0x44, 0x41, 0x06, 83 }; 84 85 static u8 hx8357_seq_vcom[] = { 86 HX8357_SET_VCOM, 0x40, 0x10, 87 }; 88 89 static u8 hx8357_seq_power_normal[] = { 90 HX8357_SET_POWER_NORMAL, 0x05, 0x12, 91 }; 92 93 static u8 hx8357_seq_panel_driving[] = { 94 HX8357_SET_PANEL_DRIVING, 0x14, 0x3b, 0x00, 0x02, 0x11, 95 }; 96 97 static u8 hx8357_seq_display_frame[] = { 98 HX8357_SET_DISPLAY_FRAME, 0x0c, 99 }; 100 101 static u8 hx8357_seq_panel_related[] = { 102 HX8357_SET_PANEL_RELATED, 0x01, 103 }; 104 105 static u8 hx8357_seq_undefined1[] = { 106 0xea, 0x03, 0x00, 0x00, 107 }; 108 109 static u8 hx8357_seq_undefined2[] = { 110 0xeb, 0x40, 0x54, 0x26, 0xdb, 111 }; 112 113 static u8 hx8357_seq_gamma[] = { 114 HX8357_SET_GAMMA, 0x00, 0x15, 0x00, 0x22, 0x00, 115 0x08, 0x77, 0x26, 0x77, 0x22, 0x04, 0x00, 116 }; 117 118 static u8 hx8357_seq_address_mode[] = { 119 HX8357_SET_ADDRESS_MODE, 0xc0, 120 }; 121 122 static u8 hx8357_seq_pixel_format[] = { 123 HX8357_SET_PIXEL_FORMAT, 124 HX8357_SET_PIXEL_FORMAT_DPI_18BIT | 125 HX8357_SET_PIXEL_FORMAT_DBI_18BIT, 126 }; 127 128 static u8 hx8357_seq_column_address[] = { 129 HX8357_SET_COLUMN_ADDRESS, 0x00, 0x00, 0x01, 0x3f, 130 }; 131 132 static u8 hx8357_seq_page_address[] = { 133 HX8357_SET_PAGE_ADDRESS, 0x00, 0x00, 0x01, 0xdf, 134 }; 135 136 static u8 hx8357_seq_rgb[] = { 137 HX8357_SET_RGB, 0x02, 138 }; 139 140 static u8 hx8357_seq_display_mode[] = { 141 HX8357_SET_DISPLAY_MODE, 142 HX8357_SET_DISPLAY_MODE_RGB_THROUGH | 143 HX8357_SET_DISPLAY_MODE_RGB_INTERFACE, 144 }; 145 146 static int hx8357_spi_write_then_read(struct lcd_device *lcdev, 147 u8 *txbuf, u16 txlen, 148 u8 *rxbuf, u16 rxlen) 149 { 150 struct hx8357_data *lcd = lcd_get_data(lcdev); 151 struct spi_message msg; 152 struct spi_transfer xfer[2]; 153 u16 *local_txbuf = NULL; 154 int ret = 0; 155 156 memset(xfer, 0, sizeof(xfer)); 157 spi_message_init(&msg); 158 159 if (txlen) { 160 int i; 161 162 local_txbuf = kcalloc(txlen, sizeof(*local_txbuf), GFP_KERNEL); 163 164 if (!local_txbuf) 165 return -ENOMEM; 166 167 for (i = 0; i < txlen; i++) { 168 local_txbuf[i] = txbuf[i]; 169 if (i > 0) 170 local_txbuf[i] |= 1 << 8; 171 } 172 173 xfer[0].len = 2 * txlen; 174 xfer[0].bits_per_word = 9; 175 xfer[0].tx_buf = local_txbuf; 176 spi_message_add_tail(&xfer[0], &msg); 177 } 178 179 if (rxlen) { 180 xfer[1].len = rxlen; 181 xfer[1].bits_per_word = 8; 182 xfer[1].rx_buf = rxbuf; 183 spi_message_add_tail(&xfer[1], &msg); 184 } 185 186 ret = spi_sync(lcd->spi, &msg); 187 if (ret < 0) 188 dev_err(&lcdev->dev, "Couldn't send SPI data\n"); 189 190 if (txlen) 191 kfree(local_txbuf); 192 193 return ret; 194 } 195 196 static inline int hx8357_spi_write_array(struct lcd_device *lcdev, 197 u8 *value, u8 len) 198 { 199 return hx8357_spi_write_then_read(lcdev, value, len, NULL, 0); 200 } 201 202 static inline int hx8357_spi_write_byte(struct lcd_device *lcdev, 203 u8 value) 204 { 205 return hx8357_spi_write_then_read(lcdev, &value, 1, NULL, 0); 206 } 207 208 static int hx8357_enter_standby(struct lcd_device *lcdev) 209 { 210 int ret; 211 212 ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_OFF); 213 if (ret < 0) 214 return ret; 215 216 usleep_range(10000, 12000); 217 218 ret = hx8357_spi_write_byte(lcdev, HX8357_ENTER_SLEEP_MODE); 219 if (ret < 0) 220 return ret; 221 222 msleep(120); 223 224 return 0; 225 } 226 227 static int hx8357_exit_standby(struct lcd_device *lcdev) 228 { 229 int ret; 230 231 ret = hx8357_spi_write_byte(lcdev, HX8357_EXIT_SLEEP_MODE); 232 if (ret < 0) 233 return ret; 234 235 msleep(120); 236 237 ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_ON); 238 if (ret < 0) 239 return ret; 240 241 return 0; 242 } 243 244 static int hx8357_lcd_init(struct lcd_device *lcdev) 245 { 246 struct hx8357_data *lcd = lcd_get_data(lcdev); 247 int ret; 248 249 /* 250 * Set the interface selection pins to SPI mode, with three 251 * wires 252 */ 253 gpio_set_value_cansleep(lcd->im_pins[0], 1); 254 gpio_set_value_cansleep(lcd->im_pins[1], 0); 255 gpio_set_value_cansleep(lcd->im_pins[2], 1); 256 257 /* Reset the screen */ 258 gpio_set_value(lcd->reset, 1); 259 usleep_range(10000, 12000); 260 gpio_set_value(lcd->reset, 0); 261 usleep_range(10000, 12000); 262 gpio_set_value(lcd->reset, 1); 263 msleep(120); 264 265 ret = hx8357_spi_write_array(lcdev, hx8357_seq_power, 266 ARRAY_SIZE(hx8357_seq_power)); 267 if (ret < 0) 268 return ret; 269 270 ret = hx8357_spi_write_array(lcdev, hx8357_seq_vcom, 271 ARRAY_SIZE(hx8357_seq_vcom)); 272 if (ret < 0) 273 return ret; 274 275 ret = hx8357_spi_write_array(lcdev, hx8357_seq_power_normal, 276 ARRAY_SIZE(hx8357_seq_power_normal)); 277 if (ret < 0) 278 return ret; 279 280 ret = hx8357_spi_write_array(lcdev, hx8357_seq_panel_driving, 281 ARRAY_SIZE(hx8357_seq_panel_driving)); 282 if (ret < 0) 283 return ret; 284 285 ret = hx8357_spi_write_array(lcdev, hx8357_seq_display_frame, 286 ARRAY_SIZE(hx8357_seq_display_frame)); 287 if (ret < 0) 288 return ret; 289 290 ret = hx8357_spi_write_array(lcdev, hx8357_seq_panel_related, 291 ARRAY_SIZE(hx8357_seq_panel_related)); 292 if (ret < 0) 293 return ret; 294 295 ret = hx8357_spi_write_array(lcdev, hx8357_seq_undefined1, 296 ARRAY_SIZE(hx8357_seq_undefined1)); 297 if (ret < 0) 298 return ret; 299 300 ret = hx8357_spi_write_array(lcdev, hx8357_seq_undefined2, 301 ARRAY_SIZE(hx8357_seq_undefined2)); 302 if (ret < 0) 303 return ret; 304 305 ret = hx8357_spi_write_array(lcdev, hx8357_seq_gamma, 306 ARRAY_SIZE(hx8357_seq_gamma)); 307 if (ret < 0) 308 return ret; 309 310 ret = hx8357_spi_write_array(lcdev, hx8357_seq_address_mode, 311 ARRAY_SIZE(hx8357_seq_address_mode)); 312 if (ret < 0) 313 return ret; 314 315 ret = hx8357_spi_write_array(lcdev, hx8357_seq_pixel_format, 316 ARRAY_SIZE(hx8357_seq_pixel_format)); 317 if (ret < 0) 318 return ret; 319 320 ret = hx8357_spi_write_array(lcdev, hx8357_seq_column_address, 321 ARRAY_SIZE(hx8357_seq_column_address)); 322 if (ret < 0) 323 return ret; 324 325 ret = hx8357_spi_write_array(lcdev, hx8357_seq_page_address, 326 ARRAY_SIZE(hx8357_seq_page_address)); 327 if (ret < 0) 328 return ret; 329 330 ret = hx8357_spi_write_array(lcdev, hx8357_seq_rgb, 331 ARRAY_SIZE(hx8357_seq_rgb)); 332 if (ret < 0) 333 return ret; 334 335 ret = hx8357_spi_write_array(lcdev, hx8357_seq_display_mode, 336 ARRAY_SIZE(hx8357_seq_display_mode)); 337 if (ret < 0) 338 return ret; 339 340 ret = hx8357_spi_write_byte(lcdev, HX8357_EXIT_SLEEP_MODE); 341 if (ret < 0) 342 return ret; 343 344 msleep(120); 345 346 ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_ON); 347 if (ret < 0) 348 return ret; 349 350 usleep_range(5000, 7000); 351 352 ret = hx8357_spi_write_byte(lcdev, HX8357_WRITE_MEMORY_START); 353 if (ret < 0) 354 return ret; 355 356 return 0; 357 } 358 359 #define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL) 360 361 static int hx8357_set_power(struct lcd_device *lcdev, int power) 362 { 363 struct hx8357_data *lcd = lcd_get_data(lcdev); 364 int ret = 0; 365 366 if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->state)) 367 ret = hx8357_exit_standby(lcdev); 368 else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->state)) 369 ret = hx8357_enter_standby(lcdev); 370 371 if (ret == 0) 372 lcd->state = power; 373 else 374 dev_warn(&lcdev->dev, "failed to set power mode %d\n", power); 375 376 return ret; 377 } 378 379 static int hx8357_get_power(struct lcd_device *lcdev) 380 { 381 struct hx8357_data *lcd = lcd_get_data(lcdev); 382 383 return lcd->state; 384 } 385 386 static struct lcd_ops hx8357_ops = { 387 .set_power = hx8357_set_power, 388 .get_power = hx8357_get_power, 389 }; 390 391 static int hx8357_probe(struct spi_device *spi) 392 { 393 struct lcd_device *lcdev; 394 struct hx8357_data *lcd; 395 int i, ret; 396 397 lcd = devm_kzalloc(&spi->dev, sizeof(*lcd), GFP_KERNEL); 398 if (!lcd) { 399 dev_err(&spi->dev, "Couldn't allocate lcd internal structure!\n"); 400 return -ENOMEM; 401 } 402 403 ret = spi_setup(spi); 404 if (ret < 0) { 405 dev_err(&spi->dev, "SPI setup failed.\n"); 406 return ret; 407 } 408 409 lcd->spi = spi; 410 411 lcd->reset = of_get_named_gpio(spi->dev.of_node, "gpios-reset", 0); 412 if (!gpio_is_valid(lcd->reset)) { 413 dev_err(&spi->dev, "Missing dt property: gpios-reset\n"); 414 return -EINVAL; 415 } 416 417 ret = devm_gpio_request_one(&spi->dev, lcd->reset, 418 GPIOF_OUT_INIT_HIGH, 419 "hx8357-reset"); 420 if (ret) { 421 dev_err(&spi->dev, 422 "failed to request gpio %d: %d\n", 423 lcd->reset, ret); 424 return -EINVAL; 425 } 426 427 for (i = 0; i < HX8357_NUM_IM_PINS; i++) { 428 lcd->im_pins[i] = of_get_named_gpio(spi->dev.of_node, 429 "im-gpios", i); 430 if (lcd->im_pins[i] == -EPROBE_DEFER) { 431 dev_info(&spi->dev, "GPIO requested is not here yet, deferring the probe\n"); 432 return -EPROBE_DEFER; 433 } 434 if (!gpio_is_valid(lcd->im_pins[i])) { 435 dev_err(&spi->dev, "Missing dt property: im-gpios\n"); 436 return -EINVAL; 437 } 438 439 ret = devm_gpio_request_one(&spi->dev, lcd->im_pins[i], 440 GPIOF_OUT_INIT_LOW, "im_pins"); 441 if (ret) { 442 dev_err(&spi->dev, "failed to request gpio %d: %d\n", 443 lcd->im_pins[i], ret); 444 return -EINVAL; 445 } 446 } 447 448 lcdev = lcd_device_register("mxsfb", &spi->dev, lcd, &hx8357_ops); 449 if (IS_ERR(lcdev)) { 450 ret = PTR_ERR(lcdev); 451 return ret; 452 } 453 spi_set_drvdata(spi, lcdev); 454 455 ret = hx8357_lcd_init(lcdev); 456 if (ret) { 457 dev_err(&spi->dev, "Couldn't initialize panel\n"); 458 goto init_error; 459 } 460 461 dev_info(&spi->dev, "Panel probed\n"); 462 463 return 0; 464 465 init_error: 466 lcd_device_unregister(lcdev); 467 return ret; 468 } 469 470 static int hx8357_remove(struct spi_device *spi) 471 { 472 struct lcd_device *lcdev = spi_get_drvdata(spi); 473 474 lcd_device_unregister(lcdev); 475 return 0; 476 } 477 478 static const struct of_device_id hx8357_dt_ids[] = { 479 { .compatible = "himax,hx8357" }, 480 {}, 481 }; 482 MODULE_DEVICE_TABLE(of, hx8357_dt_ids); 483 484 static struct spi_driver hx8357_driver = { 485 .probe = hx8357_probe, 486 .remove = hx8357_remove, 487 .driver = { 488 .name = "hx8357", 489 .of_match_table = of_match_ptr(hx8357_dt_ids), 490 }, 491 }; 492 493 module_spi_driver(hx8357_driver); 494 495 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>"); 496 MODULE_DESCRIPTION("Himax HX-8357 LCD Driver"); 497 MODULE_LICENSE("GPL"); 498