1/* 2 * Copyright © 2011 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 * 23 */ 24 25#include <linux/delay.h> 26#include <linux/kernel.h> 27#include <linux/module.h> 28#include <linux/gpio/consumer.h> 29 30#include <asm/intel_scu_ipc.h> 31 32#include "mdfld_dsi_dpi.h" 33#include "mdfld_dsi_pkg_sender.h" 34#include "mdfld_output.h" 35#include "tc35876x-dsi-lvds.h" 36 37static struct i2c_client *tc35876x_client; 38static struct i2c_client *cmi_lcd_i2c_client; 39/* Panel GPIOs */ 40static struct gpio_desc *bridge_reset; 41static struct gpio_desc *bridge_bl_enable; 42static struct gpio_desc *backlight_voltage; 43 44 45#define FLD_MASK(start, end) (((1 << ((start) - (end) + 1)) - 1) << (end)) 46#define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end)) 47 48/* DSI D-PHY Layer Registers */ 49#define D0W_DPHYCONTTX 0x0004 50#define CLW_DPHYCONTRX 0x0020 51#define D0W_DPHYCONTRX 0x0024 52#define D1W_DPHYCONTRX 0x0028 53#define D2W_DPHYCONTRX 0x002C 54#define D3W_DPHYCONTRX 0x0030 55#define COM_DPHYCONTRX 0x0038 56#define CLW_CNTRL 0x0040 57#define D0W_CNTRL 0x0044 58#define D1W_CNTRL 0x0048 59#define D2W_CNTRL 0x004C 60#define D3W_CNTRL 0x0050 61#define DFTMODE_CNTRL 0x0054 62 63/* DSI PPI Layer Registers */ 64#define PPI_STARTPPI 0x0104 65#define PPI_BUSYPPI 0x0108 66#define PPI_LINEINITCNT 0x0110 67#define PPI_LPTXTIMECNT 0x0114 68#define PPI_LANEENABLE 0x0134 69#define PPI_TX_RX_TA 0x013C 70#define PPI_CLS_ATMR 0x0140 71#define PPI_D0S_ATMR 0x0144 72#define PPI_D1S_ATMR 0x0148 73#define PPI_D2S_ATMR 0x014C 74#define PPI_D3S_ATMR 0x0150 75#define PPI_D0S_CLRSIPOCOUNT 0x0164 76#define PPI_D1S_CLRSIPOCOUNT 0x0168 77#define PPI_D2S_CLRSIPOCOUNT 0x016C 78#define PPI_D3S_CLRSIPOCOUNT 0x0170 79#define CLS_PRE 0x0180 80#define D0S_PRE 0x0184 81#define D1S_PRE 0x0188 82#define D2S_PRE 0x018C 83#define D3S_PRE 0x0190 84#define CLS_PREP 0x01A0 85#define D0S_PREP 0x01A4 86#define D1S_PREP 0x01A8 87#define D2S_PREP 0x01AC 88#define D3S_PREP 0x01B0 89#define CLS_ZERO 0x01C0 90#define D0S_ZERO 0x01C4 91#define D1S_ZERO 0x01C8 92#define D2S_ZERO 0x01CC 93#define D3S_ZERO 0x01D0 94#define PPI_CLRFLG 0x01E0 95#define PPI_CLRSIPO 0x01E4 96#define HSTIMEOUT 0x01F0 97#define HSTIMEOUTENABLE 0x01F4 98 99/* DSI Protocol Layer Registers */ 100#define DSI_STARTDSI 0x0204 101#define DSI_BUSYDSI 0x0208 102#define DSI_LANEENABLE 0x0210 103#define DSI_LANESTATUS0 0x0214 104#define DSI_LANESTATUS1 0x0218 105#define DSI_INTSTATUS 0x0220 106#define DSI_INTMASK 0x0224 107#define DSI_INTCLR 0x0228 108#define DSI_LPTXTO 0x0230 109 110/* DSI General Registers */ 111#define DSIERRCNT 0x0300 112 113/* DSI Application Layer Registers */ 114#define APLCTRL 0x0400 115#define RDPKTLN 0x0404 116 117/* Video Path Registers */ 118#define VPCTRL 0x0450 119#define HTIM1 0x0454 120#define HTIM2 0x0458 121#define VTIM1 0x045C 122#define VTIM2 0x0460 123#define VFUEN 0x0464 124 125/* LVDS Registers */ 126#define LVMX0003 0x0480 127#define LVMX0407 0x0484 128#define LVMX0811 0x0488 129#define LVMX1215 0x048C 130#define LVMX1619 0x0490 131#define LVMX2023 0x0494 132#define LVMX2427 0x0498 133#define LVCFG 0x049C 134#define LVPHY0 0x04A0 135#define LVPHY1 0x04A4 136 137/* System Registers */ 138#define SYSSTAT 0x0500 139#define SYSRST 0x0504 140 141/* GPIO Registers */ 142/*#define GPIOC 0x0520*/ 143#define GPIOO 0x0524 144#define GPIOI 0x0528 145 146/* I2C Registers */ 147#define I2CTIMCTRL 0x0540 148#define I2CMADDR 0x0544 149#define WDATAQ 0x0548 150#define RDATAQ 0x054C 151 152/* Chip/Rev Registers */ 153#define IDREG 0x0580 154 155/* Debug Registers */ 156#define DEBUG00 0x05A0 157#define DEBUG01 0x05A4 158 159/* Panel CABC registers */ 160#define PANEL_PWM_CONTROL 0x90 161#define PANEL_FREQ_DIVIDER_HI 0x91 162#define PANEL_FREQ_DIVIDER_LO 0x92 163#define PANEL_DUTY_CONTROL 0x93 164#define PANEL_MODIFY_RGB 0x94 165#define PANEL_FRAMERATE_CONTROL 0x96 166#define PANEL_PWM_MIN 0x97 167#define PANEL_PWM_REF 0x98 168#define PANEL_PWM_MAX 0x99 169#define PANEL_ALLOW_DISTORT 0x9A 170#define PANEL_BYPASS_PWMI 0x9B 171 172/* Panel color management registers */ 173#define PANEL_CM_ENABLE 0x700 174#define PANEL_CM_HUE 0x701 175#define PANEL_CM_SATURATION 0x702 176#define PANEL_CM_INTENSITY 0x703 177#define PANEL_CM_BRIGHTNESS 0x704 178#define PANEL_CM_CE_ENABLE 0x705 179#define PANEL_CM_PEAK_EN 0x710 180#define PANEL_CM_GAIN 0x711 181#define PANEL_CM_HUETABLE_START 0x730 182#define PANEL_CM_HUETABLE_END 0x747 /* inclusive */ 183 184/* Input muxing for registers LVMX0003...LVMX2427 */ 185enum { 186 INPUT_R0, /* 0 */ 187 INPUT_R1, 188 INPUT_R2, 189 INPUT_R3, 190 INPUT_R4, 191 INPUT_R5, 192 INPUT_R6, 193 INPUT_R7, 194 INPUT_G0, /* 8 */ 195 INPUT_G1, 196 INPUT_G2, 197 INPUT_G3, 198 INPUT_G4, 199 INPUT_G5, 200 INPUT_G6, 201 INPUT_G7, 202 INPUT_B0, /* 16 */ 203 INPUT_B1, 204 INPUT_B2, 205 INPUT_B3, 206 INPUT_B4, 207 INPUT_B5, 208 INPUT_B6, 209 INPUT_B7, 210 INPUT_HSYNC, /* 24 */ 211 INPUT_VSYNC, 212 INPUT_DE, 213 LOGIC_0, 214 /* 28...31 undefined */ 215}; 216 217#define INPUT_MUX(lvmx03, lvmx02, lvmx01, lvmx00) \ 218 (FLD_VAL(lvmx03, 29, 24) | FLD_VAL(lvmx02, 20, 16) | \ 219 FLD_VAL(lvmx01, 12, 8) | FLD_VAL(lvmx00, 4, 0)) 220 221/** 222 * tc35876x_regw - Write DSI-LVDS bridge register using I2C 223 * @client: struct i2c_client to use 224 * @reg: register address 225 * @value: value to write 226 * 227 * Returns 0 on success, or a negative error value. 228 */ 229static int tc35876x_regw(struct i2c_client *client, u16 reg, u32 value) 230{ 231 int r; 232 u8 tx_data[] = { 233 /* NOTE: Register address big-endian, data little-endian. */ 234 (reg >> 8) & 0xff, 235 reg & 0xff, 236 value & 0xff, 237 (value >> 8) & 0xff, 238 (value >> 16) & 0xff, 239 (value >> 24) & 0xff, 240 }; 241 struct i2c_msg msgs[] = { 242 { 243 .addr = client->addr, 244 .flags = 0, 245 .buf = tx_data, 246 .len = ARRAY_SIZE(tx_data), 247 }, 248 }; 249 250 r = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); 251 if (r < 0) { 252 dev_err(&client->dev, "%s: reg 0x%04x val 0x%08x error %d\n", 253 __func__, reg, value, r); 254 return r; 255 } 256 257 if (r < ARRAY_SIZE(msgs)) { 258 dev_err(&client->dev, "%s: reg 0x%04x val 0x%08x msgs %d\n", 259 __func__, reg, value, r); 260 return -EAGAIN; 261 } 262 263 dev_dbg(&client->dev, "%s: reg 0x%04x val 0x%08x\n", 264 __func__, reg, value); 265 266 return 0; 267} 268 269/** 270 * tc35876x_regr - Read DSI-LVDS bridge register using I2C 271 * @client: struct i2c_client to use 272 * @reg: register address 273 * @value: pointer for storing the value 274 * 275 * Returns 0 on success, or a negative error value. 276 */ 277static int tc35876x_regr(struct i2c_client *client, u16 reg, u32 *value) 278{ 279 int r; 280 u8 tx_data[] = { 281 (reg >> 8) & 0xff, 282 reg & 0xff, 283 }; 284 u8 rx_data[4]; 285 struct i2c_msg msgs[] = { 286 { 287 .addr = client->addr, 288 .flags = 0, 289 .buf = tx_data, 290 .len = ARRAY_SIZE(tx_data), 291 }, 292 { 293 .addr = client->addr, 294 .flags = I2C_M_RD, 295 .buf = rx_data, 296 .len = ARRAY_SIZE(rx_data), 297 }, 298 }; 299 300 r = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); 301 if (r < 0) { 302 dev_err(&client->dev, "%s: reg 0x%04x error %d\n", __func__, 303 reg, r); 304 return r; 305 } 306 307 if (r < ARRAY_SIZE(msgs)) { 308 dev_err(&client->dev, "%s: reg 0x%04x msgs %d\n", __func__, 309 reg, r); 310 return -EAGAIN; 311 } 312 313 *value = rx_data[0] << 24 | rx_data[1] << 16 | 314 rx_data[2] << 8 | rx_data[3]; 315 316 dev_dbg(&client->dev, "%s: reg 0x%04x value 0x%08x\n", __func__, 317 reg, *value); 318 319 return 0; 320} 321 322void tc35876x_set_bridge_reset_state(struct drm_device *dev, int state) 323{ 324 if (WARN(!tc35876x_client, "%s called before probe", __func__)) 325 return; 326 327 dev_dbg(&tc35876x_client->dev, "%s: state %d\n", __func__, state); 328 329 if (!bridge_reset) 330 return; 331 332 if (state) { 333 gpiod_set_value_cansleep(bridge_reset, 0); 334 mdelay(10); 335 } else { 336 /* Pull MIPI Bridge reset pin to Low */ 337 gpiod_set_value_cansleep(bridge_reset, 0); 338 mdelay(20); 339 /* Pull MIPI Bridge reset pin to High */ 340 gpiod_set_value_cansleep(bridge_reset, 1); 341 mdelay(40); 342 } 343} 344 345void tc35876x_configure_lvds_bridge(struct drm_device *dev) 346{ 347 struct i2c_client *i2c = tc35876x_client; 348 u32 ppi_lptxtimecnt; 349 u32 txtagocnt; 350 u32 txtasurecnt; 351 u32 id; 352 353 if (WARN(!tc35876x_client, "%s called before probe", __func__)) 354 return; 355 356 dev_dbg(&tc35876x_client->dev, "%s\n", __func__); 357 358 if (!tc35876x_regr(i2c, IDREG, &id)) 359 dev_info(&tc35876x_client->dev, "tc35876x ID 0x%08x\n", id); 360 else 361 dev_err(&tc35876x_client->dev, "Cannot read ID\n"); 362 363 ppi_lptxtimecnt = 4; 364 txtagocnt = (5 * ppi_lptxtimecnt - 3) / 4; 365 txtasurecnt = 3 * ppi_lptxtimecnt / 2; 366 tc35876x_regw(i2c, PPI_TX_RX_TA, FLD_VAL(txtagocnt, 26, 16) | 367 FLD_VAL(txtasurecnt, 10, 0)); 368 tc35876x_regw(i2c, PPI_LPTXTIMECNT, FLD_VAL(ppi_lptxtimecnt, 10, 0)); 369 370 tc35876x_regw(i2c, PPI_D0S_CLRSIPOCOUNT, FLD_VAL(1, 5, 0)); 371 tc35876x_regw(i2c, PPI_D1S_CLRSIPOCOUNT, FLD_VAL(1, 5, 0)); 372 tc35876x_regw(i2c, PPI_D2S_CLRSIPOCOUNT, FLD_VAL(1, 5, 0)); 373 tc35876x_regw(i2c, PPI_D3S_CLRSIPOCOUNT, FLD_VAL(1, 5, 0)); 374 375 /* Enabling MIPI & PPI lanes, Enable 4 lanes */ 376 tc35876x_regw(i2c, PPI_LANEENABLE, 377 BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)); 378 tc35876x_regw(i2c, DSI_LANEENABLE, 379 BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)); 380 tc35876x_regw(i2c, PPI_STARTPPI, BIT(0)); 381 tc35876x_regw(i2c, DSI_STARTDSI, BIT(0)); 382 383 /* Setting LVDS output frequency */ 384 tc35876x_regw(i2c, LVPHY0, FLD_VAL(1, 20, 16) | 385 FLD_VAL(2, 15, 14) | FLD_VAL(6, 4, 0)); /* 0x00048006 */ 386 387 /* Setting video panel control register,0x00000120 VTGen=ON ?!?!? */ 388 tc35876x_regw(i2c, VPCTRL, BIT(8) | BIT(5)); 389 390 /* Horizontal back porch and horizontal pulse width. 0x00280028 */ 391 tc35876x_regw(i2c, HTIM1, FLD_VAL(40, 24, 16) | FLD_VAL(40, 8, 0)); 392 393 /* Horizontal front porch and horizontal active video size. 0x00500500*/ 394 tc35876x_regw(i2c, HTIM2, FLD_VAL(80, 24, 16) | FLD_VAL(1280, 10, 0)); 395 396 /* Vertical back porch and vertical sync pulse width. 0x000e000a */ 397 tc35876x_regw(i2c, VTIM1, FLD_VAL(14, 23, 16) | FLD_VAL(10, 7, 0)); 398 399 /* Vertical front porch and vertical display size. 0x000e0320 */ 400 tc35876x_regw(i2c, VTIM2, FLD_VAL(14, 23, 16) | FLD_VAL(800, 10, 0)); 401 402 /* Set above HTIM1, HTIM2, VTIM1, and VTIM2 at next VSYNC. */ 403 tc35876x_regw(i2c, VFUEN, BIT(0)); 404 405 /* Soft reset LCD controller. */ 406 tc35876x_regw(i2c, SYSRST, BIT(2)); 407 408 /* LVDS-TX input muxing */ 409 tc35876x_regw(i2c, LVMX0003, 410 INPUT_MUX(INPUT_R5, INPUT_R4, INPUT_R3, INPUT_R2)); 411 tc35876x_regw(i2c, LVMX0407, 412 INPUT_MUX(INPUT_G2, INPUT_R7, INPUT_R1, INPUT_R6)); 413 tc35876x_regw(i2c, LVMX0811, 414 INPUT_MUX(INPUT_G1, INPUT_G0, INPUT_G4, INPUT_G3)); 415 tc35876x_regw(i2c, LVMX1215, 416 INPUT_MUX(INPUT_B2, INPUT_G7, INPUT_G6, INPUT_G5)); 417 tc35876x_regw(i2c, LVMX1619, 418 INPUT_MUX(INPUT_B4, INPUT_B3, INPUT_B1, INPUT_B0)); 419 tc35876x_regw(i2c, LVMX2023, 420 INPUT_MUX(LOGIC_0, INPUT_B7, INPUT_B6, INPUT_B5)); 421 tc35876x_regw(i2c, LVMX2427, 422 INPUT_MUX(INPUT_R0, INPUT_DE, INPUT_VSYNC, INPUT_HSYNC)); 423 424 /* Enable LVDS transmitter. */ 425 tc35876x_regw(i2c, LVCFG, BIT(0)); 426 427 /* Clear notifications. Don't write reserved bits. Was write 0xffffffff 428 * to 0x0288, must be in error?! */ 429 tc35876x_regw(i2c, DSI_INTCLR, FLD_MASK(31, 30) | FLD_MASK(22, 0)); 430} 431 432#define GPIOPWMCTRL 0x38F 433#define PWM0CLKDIV0 0x62 /* low byte */ 434#define PWM0CLKDIV1 0x61 /* high byte */ 435 436#define SYSTEMCLK 19200000UL /* 19.2 MHz */ 437#define PWM_FREQUENCY 9600 /* Hz */ 438 439/* f = baseclk / (clkdiv + 1) => clkdiv = (baseclk - f) / f */ 440static inline u16 calc_clkdiv(unsigned long baseclk, unsigned int f) 441{ 442 return (baseclk - f) / f; 443} 444 445static void tc35876x_brightness_init(struct drm_device *dev) 446{ 447 int ret; 448 u8 pwmctrl; 449 u16 clkdiv; 450 451 /* Make sure the PWM reference is the 19.2 MHz system clock. Read first 452 * instead of setting directly to catch potential conflicts between PWM 453 * users. */ 454 ret = intel_scu_ipc_ioread8(GPIOPWMCTRL, &pwmctrl); 455 if (ret || pwmctrl != 0x01) { 456 if (ret) 457 dev_err(&dev->pdev->dev, "GPIOPWMCTRL read failed\n"); 458 else 459 dev_warn(&dev->pdev->dev, "GPIOPWMCTRL was not set to system clock (pwmctrl = 0x%02x)\n", pwmctrl); 460 461 ret = intel_scu_ipc_iowrite8(GPIOPWMCTRL, 0x01); 462 if (ret) 463 dev_err(&dev->pdev->dev, "GPIOPWMCTRL set failed\n"); 464 } 465 466 clkdiv = calc_clkdiv(SYSTEMCLK, PWM_FREQUENCY); 467 468 ret = intel_scu_ipc_iowrite8(PWM0CLKDIV1, (clkdiv >> 8) & 0xff); 469 if (!ret) 470 ret = intel_scu_ipc_iowrite8(PWM0CLKDIV0, clkdiv & 0xff); 471 472 if (ret) 473 dev_err(&dev->pdev->dev, "PWM0CLKDIV set failed\n"); 474 else 475 dev_dbg(&dev->pdev->dev, "PWM0CLKDIV set to 0x%04x (%d Hz)\n", 476 clkdiv, PWM_FREQUENCY); 477} 478 479#define PWM0DUTYCYCLE 0x67 480 481void tc35876x_brightness_control(struct drm_device *dev, int level) 482{ 483 int ret; 484 u8 duty_val; 485 u8 panel_duty_val; 486 487 level = clamp(level, 0, MDFLD_DSI_BRIGHTNESS_MAX_LEVEL); 488 489 /* PWM duty cycle 0x00...0x63 corresponds to 0...99% */ 490 duty_val = level * 0x63 / MDFLD_DSI_BRIGHTNESS_MAX_LEVEL; 491 492 /* I won't pretend to understand this formula. The panel spec is quite 493 * bad engrish. 494 */ 495 panel_duty_val = (2 * level - 100) * 0xA9 / 496 MDFLD_DSI_BRIGHTNESS_MAX_LEVEL + 0x56; 497 498 ret = intel_scu_ipc_iowrite8(PWM0DUTYCYCLE, duty_val); 499 if (ret) 500 dev_err(&tc35876x_client->dev, "%s: ipc write fail\n", 501 __func__); 502 503 if (cmi_lcd_i2c_client) { 504 ret = i2c_smbus_write_byte_data(cmi_lcd_i2c_client, 505 PANEL_PWM_MAX, panel_duty_val); 506 if (ret < 0) 507 dev_err(&cmi_lcd_i2c_client->dev, "%s: i2c write failed\n", 508 __func__); 509 } 510} 511 512void tc35876x_toshiba_bridge_panel_off(struct drm_device *dev) 513{ 514 if (WARN(!tc35876x_client, "%s called before probe", __func__)) 515 return; 516 517 dev_dbg(&tc35876x_client->dev, "%s\n", __func__); 518 519 if (bridge_bl_enable) 520 gpiod_set_value_cansleep(bridge_bl_enable, 0); 521 522 if (backlight_voltage) 523 gpiod_set_value_cansleep(backlight_voltage, 0); 524} 525 526void tc35876x_toshiba_bridge_panel_on(struct drm_device *dev) 527{ 528 struct drm_psb_private *dev_priv = dev->dev_private; 529 530 if (WARN(!tc35876x_client, "%s called before probe", __func__)) 531 return; 532 533 dev_dbg(&tc35876x_client->dev, "%s\n", __func__); 534 535 if (backlight_voltage) { 536 gpiod_set_value_cansleep(backlight_voltage, 1); 537 msleep(260); 538 } 539 540 if (cmi_lcd_i2c_client) { 541 int ret; 542 dev_dbg(&cmi_lcd_i2c_client->dev, "setting TCON\n"); 543 /* Bit 4 is average_saving. Setting it to 1, the brightness is 544 * referenced to the average of the frame content. 0 means 545 * reference to the maximum of frame contents. Bits 3:0 are 546 * allow_distort. When set to a nonzero value, all color values 547 * between 255-allow_distort*2 and 255 are mapped to the 548 * 255-allow_distort*2 value. 549 */ 550 ret = i2c_smbus_write_byte_data(cmi_lcd_i2c_client, 551 PANEL_ALLOW_DISTORT, 0x10); 552 if (ret < 0) 553 dev_err(&cmi_lcd_i2c_client->dev, 554 "i2c write failed (%d)\n", ret); 555 ret = i2c_smbus_write_byte_data(cmi_lcd_i2c_client, 556 PANEL_BYPASS_PWMI, 0); 557 if (ret < 0) 558 dev_err(&cmi_lcd_i2c_client->dev, 559 "i2c write failed (%d)\n", ret); 560 /* Set minimum brightness value - this is tunable */ 561 ret = i2c_smbus_write_byte_data(cmi_lcd_i2c_client, 562 PANEL_PWM_MIN, 0x35); 563 if (ret < 0) 564 dev_err(&cmi_lcd_i2c_client->dev, 565 "i2c write failed (%d)\n", ret); 566 } 567 568 if (bridge_bl_enable) 569 gpiod_set_value_cansleep(bridge_bl_enable, 1); 570 571 tc35876x_brightness_control(dev, dev_priv->brightness_adjusted); 572} 573 574static struct drm_display_mode *tc35876x_get_config_mode(struct drm_device *dev) 575{ 576 struct drm_display_mode *mode; 577 578 dev_dbg(&dev->pdev->dev, "%s\n", __func__); 579 580 mode = kzalloc(sizeof(*mode), GFP_KERNEL); 581 if (!mode) 582 return NULL; 583 584 /* FIXME: do this properly. */ 585 mode->hdisplay = 1280; 586 mode->vdisplay = 800; 587 mode->hsync_start = 1360; 588 mode->hsync_end = 1400; 589 mode->htotal = 1440; 590 mode->vsync_start = 814; 591 mode->vsync_end = 824; 592 mode->vtotal = 838; 593 mode->clock = 33324 << 1; 594 595 dev_info(&dev->pdev->dev, "hdisplay(w) = %d\n", mode->hdisplay); 596 dev_info(&dev->pdev->dev, "vdisplay(h) = %d\n", mode->vdisplay); 597 dev_info(&dev->pdev->dev, "HSS = %d\n", mode->hsync_start); 598 dev_info(&dev->pdev->dev, "HSE = %d\n", mode->hsync_end); 599 dev_info(&dev->pdev->dev, "htotal = %d\n", mode->htotal); 600 dev_info(&dev->pdev->dev, "VSS = %d\n", mode->vsync_start); 601 dev_info(&dev->pdev->dev, "VSE = %d\n", mode->vsync_end); 602 dev_info(&dev->pdev->dev, "vtotal = %d\n", mode->vtotal); 603 dev_info(&dev->pdev->dev, "clock = %d\n", mode->clock); 604 605 drm_mode_set_name(mode); 606 drm_mode_set_crtcinfo(mode, 0); 607 608 mode->type |= DRM_MODE_TYPE_PREFERRED; 609 610 return mode; 611} 612 613/* DV1 Active area 216.96 x 135.6 mm */ 614#define DV1_PANEL_WIDTH 217 615#define DV1_PANEL_HEIGHT 136 616 617static int tc35876x_get_panel_info(struct drm_device *dev, int pipe, 618 struct panel_info *pi) 619{ 620 if (!dev || !pi) 621 return -EINVAL; 622 623 pi->width_mm = DV1_PANEL_WIDTH; 624 pi->height_mm = DV1_PANEL_HEIGHT; 625 626 return 0; 627} 628 629static int tc35876x_bridge_probe(struct i2c_client *client, 630 const struct i2c_device_id *id) 631{ 632 dev_info(&client->dev, "%s\n", __func__); 633 634 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 635 dev_err(&client->dev, "%s: i2c_check_functionality() failed\n", 636 __func__); 637 return -ENODEV; 638 } 639 640 bridge_reset = devm_gpiod_get_optional(&client->dev, "bridge-reset", GPIOD_OUT_LOW); 641 if (IS_ERR(bridge_reset)) 642 return PTR_ERR(bridge_reset); 643 if (bridge_reset) 644 gpiod_set_consumer_name(bridge_reset, "tc35876x bridge reset"); 645 646 bridge_bl_enable = devm_gpiod_get_optional(&client->dev, "bl-en", GPIOD_OUT_LOW); 647 if (IS_ERR(bridge_bl_enable)) 648 return PTR_ERR(bridge_bl_enable); 649 if (bridge_bl_enable) 650 gpiod_set_consumer_name(bridge_bl_enable, "tc35876x panel bl en"); 651 652 backlight_voltage = devm_gpiod_get_optional(&client->dev, "vadd", GPIOD_OUT_LOW); 653 if (IS_ERR(backlight_voltage)) 654 return PTR_ERR(backlight_voltage); 655 if (backlight_voltage) 656 gpiod_set_consumer_name(backlight_voltage, "tc35876x panel vadd"); 657 658 tc35876x_client = client; 659 660 return 0; 661} 662 663static int tc35876x_bridge_remove(struct i2c_client *client) 664{ 665 dev_dbg(&client->dev, "%s\n", __func__); 666 667 tc35876x_client = NULL; 668 669 return 0; 670} 671 672static const struct i2c_device_id tc35876x_bridge_id[] = { 673 { "i2c_disp_brig", 0 }, 674 { } 675}; 676MODULE_DEVICE_TABLE(i2c, tc35876x_bridge_id); 677 678static struct i2c_driver tc35876x_bridge_i2c_driver = { 679 .driver = { 680 .name = "i2c_disp_brig", 681 }, 682 .id_table = tc35876x_bridge_id, 683 .probe = tc35876x_bridge_probe, 684 .remove = tc35876x_bridge_remove, 685}; 686 687/* LCD panel I2C */ 688static int cmi_lcd_i2c_probe(struct i2c_client *client, 689 const struct i2c_device_id *id) 690{ 691 dev_info(&client->dev, "%s\n", __func__); 692 693 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 694 dev_err(&client->dev, "%s: i2c_check_functionality() failed\n", 695 __func__); 696 return -ENODEV; 697 } 698 699 cmi_lcd_i2c_client = client; 700 701 return 0; 702} 703 704static int cmi_lcd_i2c_remove(struct i2c_client *client) 705{ 706 dev_dbg(&client->dev, "%s\n", __func__); 707 708 cmi_lcd_i2c_client = NULL; 709 710 return 0; 711} 712 713static const struct i2c_device_id cmi_lcd_i2c_id[] = { 714 { "cmi-lcd", 0 }, 715 { } 716}; 717MODULE_DEVICE_TABLE(i2c, cmi_lcd_i2c_id); 718 719static struct i2c_driver cmi_lcd_i2c_driver = { 720 .driver = { 721 .name = "cmi-lcd", 722 }, 723 .id_table = cmi_lcd_i2c_id, 724 .probe = cmi_lcd_i2c_probe, 725 .remove = cmi_lcd_i2c_remove, 726}; 727 728/* HACK to create I2C device while it's not created by platform code */ 729#define CMI_LCD_I2C_ADAPTER 2 730#define CMI_LCD_I2C_ADDR 0x60 731 732static int cmi_lcd_hack_create_device(void) 733{ 734 struct i2c_adapter *adapter; 735 struct i2c_client *client; 736 struct i2c_board_info info = { 737 .type = "cmi-lcd", 738 .addr = CMI_LCD_I2C_ADDR, 739 }; 740 741 pr_debug("%s\n", __func__); 742 743 adapter = i2c_get_adapter(CMI_LCD_I2C_ADAPTER); 744 if (!adapter) { 745 pr_err("%s: i2c_get_adapter(%d) failed\n", __func__, 746 CMI_LCD_I2C_ADAPTER); 747 return -EINVAL; 748 } 749 750 client = i2c_new_client_device(adapter, &info); 751 if (IS_ERR(client)) { 752 pr_err("%s: creating I2C device failed\n", __func__); 753 i2c_put_adapter(adapter); 754 return PTR_ERR(client); 755 } 756 757 return 0; 758} 759 760static const struct drm_encoder_helper_funcs tc35876x_encoder_helper_funcs = { 761 .dpms = mdfld_dsi_dpi_dpms, 762 .mode_fixup = mdfld_dsi_dpi_mode_fixup, 763 .prepare = mdfld_dsi_dpi_prepare, 764 .mode_set = mdfld_dsi_dpi_mode_set, 765 .commit = mdfld_dsi_dpi_commit, 766}; 767 768const struct panel_funcs mdfld_tc35876x_funcs = { 769 .encoder_helper_funcs = &tc35876x_encoder_helper_funcs, 770 .get_config_mode = tc35876x_get_config_mode, 771 .get_panel_info = tc35876x_get_panel_info, 772}; 773 774void tc35876x_init(struct drm_device *dev) 775{ 776 int r; 777 778 dev_dbg(&dev->pdev->dev, "%s\n", __func__); 779 780 cmi_lcd_hack_create_device(); 781 782 r = i2c_add_driver(&cmi_lcd_i2c_driver); 783 if (r < 0) 784 dev_err(&dev->pdev->dev, 785 "%s: i2c_add_driver() for %s failed (%d)\n", 786 __func__, cmi_lcd_i2c_driver.driver.name, r); 787 788 r = i2c_add_driver(&tc35876x_bridge_i2c_driver); 789 if (r < 0) 790 dev_err(&dev->pdev->dev, 791 "%s: i2c_add_driver() for %s failed (%d)\n", 792 __func__, tc35876x_bridge_i2c_driver.driver.name, r); 793 794 tc35876x_brightness_init(dev); 795} 796 797void tc35876x_exit(void) 798{ 799 pr_debug("%s\n", __func__); 800 801 i2c_del_driver(&tc35876x_bridge_i2c_driver); 802 803 if (cmi_lcd_i2c_client) 804 i2c_del_driver(&cmi_lcd_i2c_driver); 805} 806