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