root/drivers/video/backlight/hx8357.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hx8357_spi_write_then_read
  2. hx8357_spi_write_array
  3. hx8357_spi_write_byte
  4. hx8357_enter_standby
  5. hx8357_exit_standby
  6. hx8357_lcd_reset
  7. hx8357_lcd_init
  8. hx8369_lcd_init
  9. hx8357_set_power
  10. hx8357_get_power
  11. hx8357_probe

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Driver for the Himax HX-8357 LCD Controller
   4  *
   5  * Copyright 2012 Free Electrons
   6  */
   7 
   8 #include <linux/delay.h>
   9 #include <linux/lcd.h>
  10 #include <linux/module.h>
  11 #include <linux/of.h>
  12 #include <linux/of_device.h>
  13 #include <linux/of_gpio.h>
  14 #include <linux/spi/spi.h>
  15 
  16 #define HX8357_NUM_IM_PINS      3
  17 
  18 #define HX8357_SWRESET                  0x01
  19 #define HX8357_GET_RED_CHANNEL          0x06
  20 #define HX8357_GET_GREEN_CHANNEL        0x07
  21 #define HX8357_GET_BLUE_CHANNEL         0x08
  22 #define HX8357_GET_POWER_MODE           0x0a
  23 #define HX8357_GET_MADCTL               0x0b
  24 #define HX8357_GET_PIXEL_FORMAT         0x0c
  25 #define HX8357_GET_DISPLAY_MODE         0x0d
  26 #define HX8357_GET_SIGNAL_MODE          0x0e
  27 #define HX8357_GET_DIAGNOSTIC_RESULT    0x0f
  28 #define HX8357_ENTER_SLEEP_MODE         0x10
  29 #define HX8357_EXIT_SLEEP_MODE          0x11
  30 #define HX8357_ENTER_PARTIAL_MODE       0x12
  31 #define HX8357_ENTER_NORMAL_MODE        0x13
  32 #define HX8357_EXIT_INVERSION_MODE      0x20
  33 #define HX8357_ENTER_INVERSION_MODE     0x21
  34 #define HX8357_SET_DISPLAY_OFF          0x28
  35 #define HX8357_SET_DISPLAY_ON           0x29
  36 #define HX8357_SET_COLUMN_ADDRESS       0x2a
  37 #define HX8357_SET_PAGE_ADDRESS         0x2b
  38 #define HX8357_WRITE_MEMORY_START       0x2c
  39 #define HX8357_READ_MEMORY_START        0x2e
  40 #define HX8357_SET_PARTIAL_AREA         0x30
  41 #define HX8357_SET_SCROLL_AREA          0x33
  42 #define HX8357_SET_TEAR_OFF             0x34
  43 #define HX8357_SET_TEAR_ON              0x35
  44 #define HX8357_SET_ADDRESS_MODE         0x36
  45 #define HX8357_SET_SCROLL_START         0x37
  46 #define HX8357_EXIT_IDLE_MODE           0x38
  47 #define HX8357_ENTER_IDLE_MODE          0x39
  48 #define HX8357_SET_PIXEL_FORMAT         0x3a
  49 #define HX8357_SET_PIXEL_FORMAT_DBI_3BIT        (0x1)
  50 #define HX8357_SET_PIXEL_FORMAT_DBI_16BIT       (0x5)
  51 #define HX8357_SET_PIXEL_FORMAT_DBI_18BIT       (0x6)
  52 #define HX8357_SET_PIXEL_FORMAT_DPI_3BIT        (0x1 << 4)
  53 #define HX8357_SET_PIXEL_FORMAT_DPI_16BIT       (0x5 << 4)
  54 #define HX8357_SET_PIXEL_FORMAT_DPI_18BIT       (0x6 << 4)
  55 #define HX8357_WRITE_MEMORY_CONTINUE    0x3c
  56 #define HX8357_READ_MEMORY_CONTINUE     0x3e
  57 #define HX8357_SET_TEAR_SCAN_LINES      0x44
  58 #define HX8357_GET_SCAN_LINES           0x45
  59 #define HX8357_READ_DDB_START           0xa1
  60 #define HX8357_SET_DISPLAY_MODE         0xb4
  61 #define HX8357_SET_DISPLAY_MODE_RGB_THROUGH     (0x3)
  62 #define HX8357_SET_DISPLAY_MODE_RGB_INTERFACE   (1 << 4)
  63 #define HX8357_SET_PANEL_DRIVING        0xc0
  64 #define HX8357_SET_DISPLAY_FRAME        0xc5
  65 #define HX8357_SET_RGB                  0xc6
  66 #define HX8357_SET_RGB_ENABLE_HIGH              (1 << 1)
  67 #define HX8357_SET_GAMMA                0xc8
  68 #define HX8357_SET_POWER                0xd0
  69 #define HX8357_SET_VCOM                 0xd1
  70 #define HX8357_SET_POWER_NORMAL         0xd2
  71 #define HX8357_SET_PANEL_RELATED        0xe9
  72 
  73 #define HX8369_SET_DISPLAY_BRIGHTNESS           0x51
  74 #define HX8369_WRITE_CABC_DISPLAY_VALUE         0x53
  75 #define HX8369_WRITE_CABC_BRIGHT_CTRL           0x55
  76 #define HX8369_WRITE_CABC_MIN_BRIGHTNESS        0x5e
  77 #define HX8369_SET_POWER                        0xb1
  78 #define HX8369_SET_DISPLAY_MODE                 0xb2
  79 #define HX8369_SET_DISPLAY_WAVEFORM_CYC         0xb4
  80 #define HX8369_SET_VCOM                         0xb6
  81 #define HX8369_SET_EXTENSION_COMMAND            0xb9
  82 #define HX8369_SET_GIP                          0xd5
  83 #define HX8369_SET_GAMMA_CURVE_RELATED          0xe0
  84 
  85 struct hx8357_data {
  86         unsigned                im_pins[HX8357_NUM_IM_PINS];
  87         unsigned                reset;
  88         struct spi_device       *spi;
  89         int                     state;
  90         bool                    use_im_pins;
  91 };
  92 
  93 static u8 hx8357_seq_power[] = {
  94         HX8357_SET_POWER, 0x44, 0x41, 0x06,
  95 };
  96 
  97 static u8 hx8357_seq_vcom[] = {
  98         HX8357_SET_VCOM, 0x40, 0x10,
  99 };
 100 
 101 static u8 hx8357_seq_power_normal[] = {
 102         HX8357_SET_POWER_NORMAL, 0x05, 0x12,
 103 };
 104 
 105 static u8 hx8357_seq_panel_driving[] = {
 106         HX8357_SET_PANEL_DRIVING, 0x14, 0x3b, 0x00, 0x02, 0x11,
 107 };
 108 
 109 static u8 hx8357_seq_display_frame[] = {
 110         HX8357_SET_DISPLAY_FRAME, 0x0c,
 111 };
 112 
 113 static u8 hx8357_seq_panel_related[] = {
 114         HX8357_SET_PANEL_RELATED, 0x01,
 115 };
 116 
 117 static u8 hx8357_seq_undefined1[] = {
 118         0xea, 0x03, 0x00, 0x00,
 119 };
 120 
 121 static u8 hx8357_seq_undefined2[] = {
 122         0xeb, 0x40, 0x54, 0x26, 0xdb,
 123 };
 124 
 125 static u8 hx8357_seq_gamma[] = {
 126         HX8357_SET_GAMMA, 0x00, 0x15, 0x00, 0x22, 0x00,
 127         0x08, 0x77, 0x26, 0x77, 0x22, 0x04, 0x00,
 128 };
 129 
 130 static u8 hx8357_seq_address_mode[] = {
 131         HX8357_SET_ADDRESS_MODE, 0xc0,
 132 };
 133 
 134 static u8 hx8357_seq_pixel_format[] = {
 135         HX8357_SET_PIXEL_FORMAT,
 136         HX8357_SET_PIXEL_FORMAT_DPI_18BIT |
 137         HX8357_SET_PIXEL_FORMAT_DBI_18BIT,
 138 };
 139 
 140 static u8 hx8357_seq_column_address[] = {
 141         HX8357_SET_COLUMN_ADDRESS, 0x00, 0x00, 0x01, 0x3f,
 142 };
 143 
 144 static u8 hx8357_seq_page_address[] = {
 145         HX8357_SET_PAGE_ADDRESS, 0x00, 0x00, 0x01, 0xdf,
 146 };
 147 
 148 static u8 hx8357_seq_rgb[] = {
 149         HX8357_SET_RGB, 0x02,
 150 };
 151 
 152 static u8 hx8357_seq_display_mode[] = {
 153         HX8357_SET_DISPLAY_MODE,
 154         HX8357_SET_DISPLAY_MODE_RGB_THROUGH |
 155         HX8357_SET_DISPLAY_MODE_RGB_INTERFACE,
 156 };
 157 
 158 static u8 hx8369_seq_write_CABC_min_brightness[] = {
 159         HX8369_WRITE_CABC_MIN_BRIGHTNESS, 0x00,
 160 };
 161 
 162 static u8 hx8369_seq_write_CABC_control[] = {
 163         HX8369_WRITE_CABC_DISPLAY_VALUE, 0x24,
 164 };
 165 
 166 static u8 hx8369_seq_set_display_brightness[] = {
 167         HX8369_SET_DISPLAY_BRIGHTNESS, 0xFF,
 168 };
 169 
 170 static u8 hx8369_seq_write_CABC_control_setting[] = {
 171         HX8369_WRITE_CABC_BRIGHT_CTRL, 0x02,
 172 };
 173 
 174 static u8 hx8369_seq_extension_command[] = {
 175         HX8369_SET_EXTENSION_COMMAND, 0xff, 0x83, 0x69,
 176 };
 177 
 178 static u8 hx8369_seq_display_related[] = {
 179         HX8369_SET_DISPLAY_MODE, 0x00, 0x2b, 0x03, 0x03, 0x70, 0x00,
 180         0xff, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x01,
 181 };
 182 
 183 static u8 hx8369_seq_panel_waveform_cycle[] = {
 184         HX8369_SET_DISPLAY_WAVEFORM_CYC, 0x0a, 0x1d, 0x80, 0x06, 0x02,
 185 };
 186 
 187 static u8 hx8369_seq_set_address_mode[] = {
 188         HX8357_SET_ADDRESS_MODE, 0x00,
 189 };
 190 
 191 static u8 hx8369_seq_vcom[] = {
 192         HX8369_SET_VCOM, 0x3e, 0x3e,
 193 };
 194 
 195 static u8 hx8369_seq_gip[] = {
 196         HX8369_SET_GIP, 0x00, 0x01, 0x03, 0x25, 0x01, 0x02, 0x28, 0x70,
 197         0x11, 0x13, 0x00, 0x00, 0x40, 0x26, 0x51, 0x37, 0x00, 0x00, 0x71,
 198         0x35, 0x60, 0x24, 0x07, 0x0f, 0x04, 0x04,
 199 };
 200 
 201 static u8 hx8369_seq_power[] = {
 202         HX8369_SET_POWER, 0x01, 0x00, 0x34, 0x03, 0x00, 0x11, 0x11, 0x32,
 203         0x2f, 0x3f, 0x3f, 0x01, 0x3a, 0x01, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6,
 204 };
 205 
 206 static u8 hx8369_seq_gamma_curve_related[] = {
 207         HX8369_SET_GAMMA_CURVE_RELATED, 0x00, 0x0d, 0x19, 0x2f, 0x3b, 0x3d,
 208         0x2e, 0x4a, 0x08, 0x0e, 0x0f, 0x14, 0x16, 0x14, 0x14, 0x14, 0x1e,
 209         0x00, 0x0d, 0x19, 0x2f, 0x3b, 0x3d, 0x2e, 0x4a, 0x08, 0x0e, 0x0f,
 210         0x14, 0x16, 0x14, 0x14, 0x14, 0x1e,
 211 };
 212 
 213 static int hx8357_spi_write_then_read(struct lcd_device *lcdev,
 214                                 u8 *txbuf, u16 txlen,
 215                                 u8 *rxbuf, u16 rxlen)
 216 {
 217         struct hx8357_data *lcd = lcd_get_data(lcdev);
 218         struct spi_message msg;
 219         struct spi_transfer xfer[2];
 220         u16 *local_txbuf = NULL;
 221         int ret = 0;
 222 
 223         memset(xfer, 0, sizeof(xfer));
 224         spi_message_init(&msg);
 225 
 226         if (txlen) {
 227                 int i;
 228 
 229                 local_txbuf = kcalloc(txlen, sizeof(*local_txbuf), GFP_KERNEL);
 230 
 231                 if (!local_txbuf)
 232                         return -ENOMEM;
 233 
 234                 for (i = 0; i < txlen; i++) {
 235                         local_txbuf[i] = txbuf[i];
 236                         if (i > 0)
 237                                 local_txbuf[i] |= 1 << 8;
 238                 }
 239 
 240                 xfer[0].len = 2 * txlen;
 241                 xfer[0].bits_per_word = 9;
 242                 xfer[0].tx_buf = local_txbuf;
 243                 spi_message_add_tail(&xfer[0], &msg);
 244         }
 245 
 246         if (rxlen) {
 247                 xfer[1].len = rxlen;
 248                 xfer[1].bits_per_word = 8;
 249                 xfer[1].rx_buf = rxbuf;
 250                 spi_message_add_tail(&xfer[1], &msg);
 251         }
 252 
 253         ret = spi_sync(lcd->spi, &msg);
 254         if (ret < 0)
 255                 dev_err(&lcdev->dev, "Couldn't send SPI data\n");
 256 
 257         if (txlen)
 258                 kfree(local_txbuf);
 259 
 260         return ret;
 261 }
 262 
 263 static inline int hx8357_spi_write_array(struct lcd_device *lcdev,
 264                                         u8 *value, u8 len)
 265 {
 266         return hx8357_spi_write_then_read(lcdev, value, len, NULL, 0);
 267 }
 268 
 269 static inline int hx8357_spi_write_byte(struct lcd_device *lcdev,
 270                                         u8 value)
 271 {
 272         return hx8357_spi_write_then_read(lcdev, &value, 1, NULL, 0);
 273 }
 274 
 275 static int hx8357_enter_standby(struct lcd_device *lcdev)
 276 {
 277         int ret;
 278 
 279         ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_OFF);
 280         if (ret < 0)
 281                 return ret;
 282 
 283         usleep_range(10000, 12000);
 284 
 285         ret = hx8357_spi_write_byte(lcdev, HX8357_ENTER_SLEEP_MODE);
 286         if (ret < 0)
 287                 return ret;
 288 
 289         /*
 290          * The controller needs 120ms when entering in sleep mode before we can
 291          * send the command to go off sleep mode
 292          */
 293         msleep(120);
 294 
 295         return 0;
 296 }
 297 
 298 static int hx8357_exit_standby(struct lcd_device *lcdev)
 299 {
 300         int ret;
 301 
 302         ret = hx8357_spi_write_byte(lcdev, HX8357_EXIT_SLEEP_MODE);
 303         if (ret < 0)
 304                 return ret;
 305 
 306         /*
 307          * The controller needs 120ms when exiting from sleep mode before we
 308          * can send the command to enter in sleep mode
 309          */
 310         msleep(120);
 311 
 312         ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_ON);
 313         if (ret < 0)
 314                 return ret;
 315 
 316         return 0;
 317 }
 318 
 319 static void hx8357_lcd_reset(struct lcd_device *lcdev)
 320 {
 321         struct hx8357_data *lcd = lcd_get_data(lcdev);
 322 
 323         /* Reset the screen */
 324         gpio_set_value(lcd->reset, 1);
 325         usleep_range(10000, 12000);
 326         gpio_set_value(lcd->reset, 0);
 327         usleep_range(10000, 12000);
 328         gpio_set_value(lcd->reset, 1);
 329 
 330         /* The controller needs 120ms to recover from reset */
 331         msleep(120);
 332 }
 333 
 334 static int hx8357_lcd_init(struct lcd_device *lcdev)
 335 {
 336         struct hx8357_data *lcd = lcd_get_data(lcdev);
 337         int ret;
 338 
 339         /*
 340          * Set the interface selection pins to SPI mode, with three
 341          * wires
 342          */
 343         if (lcd->use_im_pins) {
 344                 gpio_set_value_cansleep(lcd->im_pins[0], 1);
 345                 gpio_set_value_cansleep(lcd->im_pins[1], 0);
 346                 gpio_set_value_cansleep(lcd->im_pins[2], 1);
 347         }
 348 
 349         ret = hx8357_spi_write_array(lcdev, hx8357_seq_power,
 350                                 ARRAY_SIZE(hx8357_seq_power));
 351         if (ret < 0)
 352                 return ret;
 353 
 354         ret = hx8357_spi_write_array(lcdev, hx8357_seq_vcom,
 355                                 ARRAY_SIZE(hx8357_seq_vcom));
 356         if (ret < 0)
 357                 return ret;
 358 
 359         ret = hx8357_spi_write_array(lcdev, hx8357_seq_power_normal,
 360                                 ARRAY_SIZE(hx8357_seq_power_normal));
 361         if (ret < 0)
 362                 return ret;
 363 
 364         ret = hx8357_spi_write_array(lcdev, hx8357_seq_panel_driving,
 365                                 ARRAY_SIZE(hx8357_seq_panel_driving));
 366         if (ret < 0)
 367                 return ret;
 368 
 369         ret = hx8357_spi_write_array(lcdev, hx8357_seq_display_frame,
 370                                 ARRAY_SIZE(hx8357_seq_display_frame));
 371         if (ret < 0)
 372                 return ret;
 373 
 374         ret = hx8357_spi_write_array(lcdev, hx8357_seq_panel_related,
 375                                 ARRAY_SIZE(hx8357_seq_panel_related));
 376         if (ret < 0)
 377                 return ret;
 378 
 379         ret = hx8357_spi_write_array(lcdev, hx8357_seq_undefined1,
 380                                 ARRAY_SIZE(hx8357_seq_undefined1));
 381         if (ret < 0)
 382                 return ret;
 383 
 384         ret = hx8357_spi_write_array(lcdev, hx8357_seq_undefined2,
 385                                 ARRAY_SIZE(hx8357_seq_undefined2));
 386         if (ret < 0)
 387                 return ret;
 388 
 389         ret = hx8357_spi_write_array(lcdev, hx8357_seq_gamma,
 390                                 ARRAY_SIZE(hx8357_seq_gamma));
 391         if (ret < 0)
 392                 return ret;
 393 
 394         ret = hx8357_spi_write_array(lcdev, hx8357_seq_address_mode,
 395                                 ARRAY_SIZE(hx8357_seq_address_mode));
 396         if (ret < 0)
 397                 return ret;
 398 
 399         ret = hx8357_spi_write_array(lcdev, hx8357_seq_pixel_format,
 400                                 ARRAY_SIZE(hx8357_seq_pixel_format));
 401         if (ret < 0)
 402                 return ret;
 403 
 404         ret = hx8357_spi_write_array(lcdev, hx8357_seq_column_address,
 405                                 ARRAY_SIZE(hx8357_seq_column_address));
 406         if (ret < 0)
 407                 return ret;
 408 
 409         ret = hx8357_spi_write_array(lcdev, hx8357_seq_page_address,
 410                                 ARRAY_SIZE(hx8357_seq_page_address));
 411         if (ret < 0)
 412                 return ret;
 413 
 414         ret = hx8357_spi_write_array(lcdev, hx8357_seq_rgb,
 415                                 ARRAY_SIZE(hx8357_seq_rgb));
 416         if (ret < 0)
 417                 return ret;
 418 
 419         ret = hx8357_spi_write_array(lcdev, hx8357_seq_display_mode,
 420                                 ARRAY_SIZE(hx8357_seq_display_mode));
 421         if (ret < 0)
 422                 return ret;
 423 
 424         ret = hx8357_spi_write_byte(lcdev, HX8357_EXIT_SLEEP_MODE);
 425         if (ret < 0)
 426                 return ret;
 427 
 428         /*
 429          * The controller needs 120ms to fully recover from exiting sleep mode
 430          */
 431         msleep(120);
 432 
 433         ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_ON);
 434         if (ret < 0)
 435                 return ret;
 436 
 437         usleep_range(5000, 7000);
 438 
 439         ret = hx8357_spi_write_byte(lcdev, HX8357_WRITE_MEMORY_START);
 440         if (ret < 0)
 441                 return ret;
 442 
 443         return 0;
 444 }
 445 
 446 static int hx8369_lcd_init(struct lcd_device *lcdev)
 447 {
 448         int ret;
 449 
 450         ret = hx8357_spi_write_array(lcdev, hx8369_seq_extension_command,
 451                                 ARRAY_SIZE(hx8369_seq_extension_command));
 452         if (ret < 0)
 453                 return ret;
 454         usleep_range(10000, 12000);
 455 
 456         ret = hx8357_spi_write_array(lcdev, hx8369_seq_display_related,
 457                                 ARRAY_SIZE(hx8369_seq_display_related));
 458         if (ret < 0)
 459                 return ret;
 460 
 461         ret = hx8357_spi_write_array(lcdev, hx8369_seq_panel_waveform_cycle,
 462                                 ARRAY_SIZE(hx8369_seq_panel_waveform_cycle));
 463         if (ret < 0)
 464                 return ret;
 465 
 466         ret = hx8357_spi_write_array(lcdev, hx8369_seq_set_address_mode,
 467                                 ARRAY_SIZE(hx8369_seq_set_address_mode));
 468         if (ret < 0)
 469                 return ret;
 470 
 471         ret = hx8357_spi_write_array(lcdev, hx8369_seq_vcom,
 472                                 ARRAY_SIZE(hx8369_seq_vcom));
 473         if (ret < 0)
 474                 return ret;
 475 
 476         ret = hx8357_spi_write_array(lcdev, hx8369_seq_gip,
 477                                 ARRAY_SIZE(hx8369_seq_gip));
 478         if (ret < 0)
 479                 return ret;
 480 
 481         ret = hx8357_spi_write_array(lcdev, hx8369_seq_power,
 482                                 ARRAY_SIZE(hx8369_seq_power));
 483         if (ret < 0)
 484                 return ret;
 485 
 486         ret = hx8357_spi_write_byte(lcdev, HX8357_EXIT_SLEEP_MODE);
 487         if (ret < 0)
 488                 return ret;
 489 
 490         /*
 491          * The controller needs 120ms to fully recover from exiting sleep mode
 492          */
 493         msleep(120);
 494 
 495         ret = hx8357_spi_write_array(lcdev, hx8369_seq_gamma_curve_related,
 496                                 ARRAY_SIZE(hx8369_seq_gamma_curve_related));
 497         if (ret < 0)
 498                 return ret;
 499 
 500         ret = hx8357_spi_write_byte(lcdev, HX8357_EXIT_SLEEP_MODE);
 501         if (ret < 0)
 502                 return ret;
 503         usleep_range(1000, 1200);
 504 
 505         ret = hx8357_spi_write_array(lcdev, hx8369_seq_write_CABC_control,
 506                                 ARRAY_SIZE(hx8369_seq_write_CABC_control));
 507         if (ret < 0)
 508                 return ret;
 509         usleep_range(10000, 12000);
 510 
 511         ret = hx8357_spi_write_array(lcdev,
 512                         hx8369_seq_write_CABC_control_setting,
 513                         ARRAY_SIZE(hx8369_seq_write_CABC_control_setting));
 514         if (ret < 0)
 515                 return ret;
 516 
 517         ret = hx8357_spi_write_array(lcdev,
 518                         hx8369_seq_write_CABC_min_brightness,
 519                         ARRAY_SIZE(hx8369_seq_write_CABC_min_brightness));
 520         if (ret < 0)
 521                 return ret;
 522         usleep_range(10000, 12000);
 523 
 524         ret = hx8357_spi_write_array(lcdev, hx8369_seq_set_display_brightness,
 525                                 ARRAY_SIZE(hx8369_seq_set_display_brightness));
 526         if (ret < 0)
 527                 return ret;
 528 
 529         ret = hx8357_spi_write_byte(lcdev, HX8357_SET_DISPLAY_ON);
 530         if (ret < 0)
 531                 return ret;
 532 
 533         return 0;
 534 }
 535 
 536 #define POWER_IS_ON(pwr)        ((pwr) <= FB_BLANK_NORMAL)
 537 
 538 static int hx8357_set_power(struct lcd_device *lcdev, int power)
 539 {
 540         struct hx8357_data *lcd = lcd_get_data(lcdev);
 541         int ret = 0;
 542 
 543         if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->state))
 544                 ret = hx8357_exit_standby(lcdev);
 545         else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->state))
 546                 ret = hx8357_enter_standby(lcdev);
 547 
 548         if (ret == 0)
 549                 lcd->state = power;
 550         else
 551                 dev_warn(&lcdev->dev, "failed to set power mode %d\n", power);
 552 
 553         return ret;
 554 }
 555 
 556 static int hx8357_get_power(struct lcd_device *lcdev)
 557 {
 558         struct hx8357_data *lcd = lcd_get_data(lcdev);
 559 
 560         return lcd->state;
 561 }
 562 
 563 static struct lcd_ops hx8357_ops = {
 564         .set_power      = hx8357_set_power,
 565         .get_power      = hx8357_get_power,
 566 };
 567 
 568 static const struct of_device_id hx8357_dt_ids[] = {
 569         {
 570                 .compatible = "himax,hx8357",
 571                 .data = hx8357_lcd_init,
 572         },
 573         {
 574                 .compatible = "himax,hx8369",
 575                 .data = hx8369_lcd_init,
 576         },
 577         {},
 578 };
 579 MODULE_DEVICE_TABLE(of, hx8357_dt_ids);
 580 
 581 static int hx8357_probe(struct spi_device *spi)
 582 {
 583         struct lcd_device *lcdev;
 584         struct hx8357_data *lcd;
 585         const struct of_device_id *match;
 586         int i, ret;
 587 
 588         lcd = devm_kzalloc(&spi->dev, sizeof(*lcd), GFP_KERNEL);
 589         if (!lcd)
 590                 return -ENOMEM;
 591 
 592         ret = spi_setup(spi);
 593         if (ret < 0) {
 594                 dev_err(&spi->dev, "SPI setup failed.\n");
 595                 return ret;
 596         }
 597 
 598         lcd->spi = spi;
 599 
 600         match = of_match_device(hx8357_dt_ids, &spi->dev);
 601         if (!match || !match->data)
 602                 return -EINVAL;
 603 
 604         lcd->reset = of_get_named_gpio(spi->dev.of_node, "gpios-reset", 0);
 605         if (!gpio_is_valid(lcd->reset)) {
 606                 dev_err(&spi->dev, "Missing dt property: gpios-reset\n");
 607                 return -EINVAL;
 608         }
 609 
 610         ret = devm_gpio_request_one(&spi->dev, lcd->reset,
 611                                     GPIOF_OUT_INIT_HIGH,
 612                                     "hx8357-reset");
 613         if (ret) {
 614                 dev_err(&spi->dev,
 615                         "failed to request gpio %d: %d\n",
 616                         lcd->reset, ret);
 617                 return -EINVAL;
 618         }
 619 
 620         if (of_find_property(spi->dev.of_node, "im-gpios", NULL)) {
 621                 lcd->use_im_pins = 1;
 622 
 623                 for (i = 0; i < HX8357_NUM_IM_PINS; i++) {
 624                         lcd->im_pins[i] = of_get_named_gpio(spi->dev.of_node,
 625                                                             "im-gpios", i);
 626                         if (lcd->im_pins[i] == -EPROBE_DEFER) {
 627                                 dev_info(&spi->dev, "GPIO requested is not here yet, deferring the probe\n");
 628                                 return -EPROBE_DEFER;
 629                         }
 630                         if (!gpio_is_valid(lcd->im_pins[i])) {
 631                                 dev_err(&spi->dev, "Missing dt property: im-gpios\n");
 632                                 return -EINVAL;
 633                         }
 634 
 635                         ret = devm_gpio_request_one(&spi->dev, lcd->im_pins[i],
 636                                                     GPIOF_OUT_INIT_LOW,
 637                                                     "im_pins");
 638                         if (ret) {
 639                                 dev_err(&spi->dev, "failed to request gpio %d: %d\n",
 640                                         lcd->im_pins[i], ret);
 641                                 return -EINVAL;
 642                         }
 643                 }
 644         } else {
 645                 lcd->use_im_pins = 0;
 646         }
 647 
 648         lcdev = devm_lcd_device_register(&spi->dev, "mxsfb", &spi->dev, lcd,
 649                                         &hx8357_ops);
 650         if (IS_ERR(lcdev)) {
 651                 ret = PTR_ERR(lcdev);
 652                 return ret;
 653         }
 654         spi_set_drvdata(spi, lcdev);
 655 
 656         hx8357_lcd_reset(lcdev);
 657 
 658         ret = ((int (*)(struct lcd_device *))match->data)(lcdev);
 659         if (ret) {
 660                 dev_err(&spi->dev, "Couldn't initialize panel\n");
 661                 return ret;
 662         }
 663 
 664         dev_info(&spi->dev, "Panel probed\n");
 665 
 666         return 0;
 667 }
 668 
 669 static struct spi_driver hx8357_driver = {
 670         .probe  = hx8357_probe,
 671         .driver = {
 672                 .name = "hx8357",
 673                 .of_match_table = hx8357_dt_ids,
 674         },
 675 };
 676 
 677 module_spi_driver(hx8357_driver);
 678 
 679 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
 680 MODULE_DESCRIPTION("Himax HX-8357 LCD Driver");
 681 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */