Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
tc35876x-dsi-lvds.c
Go to the documentation of this file.
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 
34 static struct i2c_client *tc35876x_client;
35 static 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 */
177 enum {
178  INPUT_R0, /* 0 */
186  INPUT_G0, /* 8 */
194  INPUT_B0, /* 16 */
202  INPUT_HSYNC, /* 24 */
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 
221 static 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 
269 static 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 
315 {
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) {
330  mdelay(10);
331  } else {
332  /* Pull MIPI Bridge reset pin to Low */
334  mdelay(20);
335  /* Pull MIPI Bridge reset pin to High */
337  mdelay(40);
338  }
339 }
340 
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,
407  tc35876x_regw(i2c, LVMX0407,
409  tc35876x_regw(i2c, LVMX0811,
411  tc35876x_regw(i2c, LVMX1215,
413  tc35876x_regw(i2c, LVMX1619,
415  tc35876x_regw(i2c, LVMX2023,
417  tc35876x_regw(i2c, LVMX2427,
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 */
436 static inline u16 calc_clkdiv(unsigned long baseclk, unsigned int f)
437 {
438  return (baseclk - f) / f;
439 }
440 
441 static 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 
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 /
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 
509 {
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)
521 
522  if (pdata->gpio_panel_vadd != -1)
524 }
525 
527 {
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) {
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)
573 
575 }
576 
577 static 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 
620 static 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 
628 
629  return 0;
630 }
631 
632 static int tc35876x_bridge_probe(struct i2c_client *client,
633  const struct i2c_device_id *id)
634 {
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");
654  }
655 
656  if (pdata->gpio_panel_bl_en != -1) {
657  gpio_request(pdata->gpio_panel_bl_en, "tc35876x panel bl en");
659  }
660 
661  if (pdata->gpio_panel_vadd != -1) {
662  gpio_request(pdata->gpio_panel_vadd, "tc35876x panel vadd");
664  }
665 
666  tc35876x_client = client;
667 
668  return 0;
669 }
670 
671 static 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)
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 
691 static const struct i2c_device_id tc35876x_bridge_id[] = {
692  { "i2c_disp_brig", 0 },
693  { }
694 };
695 MODULE_DEVICE_TABLE(i2c, tc35876x_bridge_id);
696 
697 static 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 = __devexit_p(tc35876x_bridge_remove),
704 };
705 
706 /* LCD panel I2C */
707 static 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 
723 static 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 
732 static const struct i2c_device_id cmi_lcd_i2c_id[] = {
733  { "cmi-lcd", 0 },
734  { }
735 };
736 MODULE_DEVICE_TABLE(i2c, cmi_lcd_i2c_id);
737 
738 static 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 = __devexit_p(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 
751 static 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 
763  if (!adapter) {
764  pr_err("%s: i2c_get_adapter(%d) failed\n", __func__,
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 
779 static 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 
787 static const struct drm_encoder_funcs tc35876x_encoder_funcs = {
788  .destroy = drm_encoder_cleanup,
789 };
790 
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 
798 void 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 
821 void 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 }