upload tizen1.0 source
[kernel/linux-2.6.36.git] / drivers / media / video / samsung / tvout / mhl / sii9234.c
1 /*
2  * Copyright (C) 2011 Samsung Electronics
3  *
4  * Authors: Adam Hampson <ahampson@sta.samsung.com>
5  *          Erik Gilling <konkers@android.com>
6  *
7  * Additional contributions by : Shankar Bandal <shankar.b@samsung.com>
8  *                               Dharam Kumar <dharam.kr@samsung.com>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
23  *
24  */
25
26 #include <linux/delay.h>
27 #include <linux/err.h>
28 #include <linux/gpio.h>
29 #include <linux/i2c.h>
30 #include <linux/interrupt.h>
31 #include <linux/irq.h>
32 #include <linux/kernel.h>
33 #include <linux/module.h>
34 #include <linux/mutex.h>
35 #include <linux/platform_device.h>
36 #include <linux/sii9234.h>
37 #include <linux/slab.h>
38 #include <linux/wait.h>
39 #include <linux/file.h>
40 #include <linux/uaccess.h>
41 #include <linux/proc_fs.h>
42 #include <linux/device.h>
43 #include <linux/wakelock.h>
44
45 /*temp*/
46 #ifndef CONFIG_SII9234_CBUS
47 #define CONFIG_SII9234_CBUS
48 #endif
49
50 #ifdef CONFIG_SII9234_CBUS
51 #ifndef CONFIG_SII9234_RCP
52 #define CONFIG_SII9234_RCP      1
53 #endif
54 #endif
55
56 #ifndef CONFIG_SS_FACTORY
57 #define CONFIG_SS_FACTORY       1
58 #endif
59
60 #ifdef CONFIG_SII9234_RCP
61 #include <linux/sii9234_rcp.h>
62 #include <linux/input.h>
63 #endif
64
65 #define CONFIG_MHL_DEBUG
66
67 #undef pr_debug
68 #ifdef CONFIG_MHL_DEBUG
69 #define pr_debug(fmt, ...)                                      \
70 do {                                                            \
71         if (unlikely(mhl_dbg_flag == 1)) {                      \
72                 printk(KERN_INFO fmt, ##__VA_ARGS__);           \
73         }                                                       \
74 } while (0)
75 int mhl_dbg_flag;
76 #else
77 #define pr_debug(fmt, ...)
78 #endif
79
80 #define T_SRC_CBUS_FLOAT                50
81 #define T_WAIT_TIMEOUT_RGND_INT         2000
82 #define T_WAIT_TIMEOUT_DISC_INT         1000
83 #define T_WAIT_TIMEOUT_RSEN_INT         200
84 #define T_HPD_WIDTH                     110
85 #define T_SRC_RXSENSE_DEGLITCH          110
86 #define T_SRC_CBUS_DEGLITCH             2
87 #define T_TPKT_SENDER_TIMEOUT           100
88
89 #define T_SRC_VBUS_CBUS_TO_STABLE       200
90 #define T_SRC_WAKE_PULSE_WIDTH_1        19
91 #define T_SRC_WAKE_PULSE_WIDTH_2        60
92 #define T_SRC_WAKE_TO_DISCOVER          500
93 #define T_SRC_VBUS_CBUS_T0_STABLE       500
94
95 /* MHL TX Addr 0x72 Registers */
96 #define MHL_TX_IDL_REG                  0x02
97 #define MHL_TX_IDH_REG                  0x03
98 #define MHL_TX_REV_REG                  0x04
99 #define MHL_TX_SRST                     0x05
100 #define MHL_TX_INTR1_REG                0x71
101 #define MHL_TX_INTR2_REG                0x72
102 #define MHL_TX_INTR3_REG                0x73
103 #define MHL_TX_INTR4_REG                0x74
104 #define MHL_TX_INTR1_ENABLE_REG         0x75
105 #define MHL_TX_INTR2_ENABLE_REG         0x76
106 #define MHL_TX_INTR3_ENABLE_REG         0x77
107 #define MHL_TX_INTR4_ENABLE_REG         0x78
108
109 #define MHL_TX_INT_CTRL_REG             0x79
110 #define   INTR_POLARITY         (1 << 1)
111 #define   INTR_OPEN_DRAIN       (1 << 2)
112 #define   HPD_OUT_OVR_EN        (1 << 4)
113 #define   HPD_OUT_OVR_VAL       (1 << 5)
114 #define   HPD_OUT_OPEN_DRAIN    (1 << 6)
115
116 #define MHL_TX_TMDS_CCTRL               0x80
117
118 #define MHL_TX_DISC_CTRL1_REG           0x90
119 #define MHL_TX_DISC_CTRL2_REG           0x91
120 #define MHL_TX_DISC_CTRL3_REG           0x92
121 #define MHL_TX_DISC_CTRL4_REG           0x93
122
123 #define MHL_TX_DISC_CTRL5_REG           0x94
124 #define MHL_TX_DISC_CTRL6_REG           0x95
125 #define MHL_TX_DISC_CTRL7_REG           0x96
126 #define MHL_TX_DISC_CTRL8_REG           0x97
127 #define MHL_TX_STAT1_REG                0x98
128 #define MHL_TX_STAT2_REG                0x99
129
130 #define MHL_TX_MHLTX_CTL1_REG           0xA0
131 #define MHL_TX_MHLTX_CTL2_REG           0xA1
132 #define MHL_TX_MHLTX_CTL4_REG           0xA3
133 #define MHL_TX_MHLTX_CTL6_REG           0xA5
134 #define MHL_TX_MHLTX_CTL7_REG           0xA6
135
136 /* MHL TX SYS STAT Registers */
137 #define MHL_TX_SYSSTAT_REG              0x09
138
139 /* MHL TX SYS STAT Register Bits */
140 #define RSEN_STATUS                     (1<<2)
141
142 /* MHL TX INTR4 Register Bits */
143 #define RGND_READY_INT                  (1<<6)
144 #define VBUS_LOW_INT                    (1<<5)
145 #define CBUS_LKOUT_INT                  (1<<4)
146 #define MHL_DISC_FAIL_INT               (1<<3)
147 #define MHL_EST_INT                     (1<<2)
148
149 /* MHL TX INTR4_ENABLE 0x78 Register Bits */
150 #define RGND_READY_MASK                 (1<<6)
151 #define CBUS_LKOUT_MASK                 (1<<4)
152 #define MHL_DISC_FAIL_MASK              (1<<3)
153 #define MHL_EST_MASK                    (1<<2)
154
155 /* MHL TX INTR1 Register Bits*/
156 #define HPD_CHANGE_INT                  (1<<6)
157 #define RSEN_CHANGE_INT                 (1<<5)
158
159 /* MHL TX INTR1_ENABLE 0x75 Register Bits*/
160 #define HPD_CHANGE_INT_MASK             (1<<6)
161 #define RSEN_CHANGE_INT_MASK            (1<<5)
162
163 #define CBUS_CONFIG_REG                 0x07
164
165 #define CBUS_INT_STATUS_1_REG           0x08
166 #define CBUS_INT_1_MASK                 0x09
167
168 #define START_MSC_RESERVED              (1<<0)
169 #define START_MSC_MSG                   (1<<1)
170 #define START_READ_DEVCAP               (1<<2)
171 #define START_WRITE_STAT_INT            (1<<3)
172 #define START_WRITE_BURST               (1<<4)
173
174 #define CBUS_MSC_RAP_CONTENT_ON         0x10
175 #define CBUS_MSC_RAP_CONTENT_OFF        0x11
176 #define CBUS_MSC_COMMAND_START          0x12
177 #define CBUS_MSC_OFFSET_REG             0x13
178 #define CBUS_MSC_FIRST_DATA_OUT         0x14
179 #define CBUS_MSC_SECOND_DATA_OUT        0x15
180 #define CBUS_MSC_FIRST_DATA_IN          0x16
181 #define CBUS_MSC_MSG_CMD_IN             0x18
182 #define CBUS_MSC_MSG_DATA_IN            0x19
183 #define CBUS_INT_STATUS_2_REG           0x1E
184 #define CBUS_INT_2_MASK                 0x1F
185 #define CBUS_LINK_CONTROL_2_REG         0x31
186
187 #define CBUS_INT_STATUS_2_REG           0x1E
188
189 /* MHL Interrupt Registers */
190 #define CBUS_MHL_INTR_REG_0             0xA0
191
192 #define CBUS_MHL_INTR_REG_1             0xA1
193 #define   MHL_INT_EDID_CHG      (1<<1)
194
195 #define CBUS_MHL_INTR_REG_2             0xA2
196 #define CBUS_MHL_INTR_REG_3             0xA3
197
198 /* MHL Status Registers */
199 #define CBUS_MHL_STATUS_REG_0           0xB0
200 #define   MHL_STATUS_DCAP_READY (1<<0)
201
202 #define CBUS_MHL_STATUS_REG_1           0xB1
203 #define CBUS_MHL_STATUS_REG_2           0xB2
204 #define CBUS_MHL_STATUS_REG_3           0xB3
205
206 /* CBUS INTR1 STATUS Register bits */
207 #define MSC_RESP_ABORT                  (1<<6)
208 #define MSC_REQ_ABORT                   (1<<5)
209 #define MSC_REQ_DONE                    (1<<4)
210 #define MSC_MSG_RECD                    (1<<3)
211 #define CBUS_DDC_ABORT                  (1<<2)
212
213 /* CBUS INTR1 STATUS 0x09 Enable Mask*/
214 #define MSC_RESP_ABORT_MASK             (1<<6)
215 #define MSC_REQ_ABORT_MASK              (1<<5)
216 #define MSC_REQ_DONE_MASK               (1<<4)
217 #define MSC_MSG_RECD_MASK               (1<<3)
218 #define CBUS_DDC_ABORT_MASK             (1<<2)
219
220 /* CBUS INTR2 STATUS Register bits */
221 #define WRT_STAT_RECD                   (1<<3)
222 #define SET_INT_RECD                    (1<<2)
223 #define WRT_BURST_RECD                  (1<<0)
224
225 /* CBUS INTR2 STATUS 0x1F Enable Mask*/
226 #define WRT_STAT_RECD_MASK              (1<<3)
227 #define SET_INT_RECD_MASK               (1<<2)
228 #define WRT_BURST_RECD_MASK             (1<<0)
229
230 #define CBUS_INTR_STATUS_1_ENABLE_MASK (MSC_RESP_ABORT_MASK |\
231                                         MSC_REQ_ABORT_MASK |\
232                                         MSC_REQ_DONE_MASK |\
233                                         MSC_MSG_RECD_MASK |\
234                                         CBUS_DDC_ABORT_MASK)
235
236 #define CBUS_INTR_STATUS_2_ENABLE_MASK (WRT_STAT_RECD_MASK |\
237                                         SET_INT_RECD_MASK)
238
239 #define MHL_INT_EDID_CHG                (1<<1)
240
241 #define MHL_RCHANGE_INT                 0x20
242 #define MHL_DCHANGE_INT                 0x21
243 #define MHL_INT_DCAP_CHG                (1<<0)
244 #define MHL_INT_DSCR_CHG                (1<<1)
245 #define MHL_INT_REQ_WRT                 (1<<2)
246 #define MHL_INT_GRT_WRT                 (1<<3)
247
248 /* CBUS Control Registers*/
249 /* Retry count for all MSC commands*/
250 #define MSC_RETRY_FAIL_LIM_REG          0x1D
251
252 #define MSC_REQ_ABORT_REASON_REG        0x0D
253
254 #define MSC_RESP_ABORT_REASON_REG       0x0E
255
256 /* MSC Requestor/Responder Abort Reason Register bits*/
257 #define ABORT_BY_PEER                   (1<<7)
258 #define UNDEF_CMD                       (1<<3)
259 #define TIMEOUT                         (1<<2)
260 #define PROTO_ERROR                     (1<<1)
261 #define MAX_FAIL                        (1<<0)
262
263 #define REG_CBUS_INTR_STATUS            0x08
264 /* Responder aborted DDC command at translation layer */
265 #define BIT_DDC_ABORT                   (1<<2)
266 /* Responder sent a VS_MSG packet (response data or command.) */
267 #define BIT_MSC_MSG_RCV                 (1<<3)
268 /* Responder sent ACK packet (not VS_MSG) */
269 #define BIT_MSC_XFR_DONE                (1<<4)
270 /* Command send aborted on TX side */
271 #define BIT_MSC_XFR_ABORT               (1<<5)
272 #define BIT_MSC_ABORT                   (1<<6)
273
274 /* Set HPD came from Downstream, */
275 #define SET_HPD_DOWNSTREAM              (1<<6)
276
277 /* MHL TX DISC1 Register Bits */
278 #define DISC_EN                         (1<<0)
279
280 /* MHL TX DISC2 Register Bits */
281 #define SKIP_GND                        (1<<6)
282 #define ATT_THRESH_SHIFT                0x04
283 #define ATT_THRESH_MASK                 (0x03 << ATT_THRESH_SHIFT)
284 #define USB_D_OEN                       (1<<3)
285 #define DEGLITCH_TIME_MASK              0x07
286 #define DEGLITCH_TIME_2MS               0
287 #define DEGLITCH_TIME_4MS               1
288 #define DEGLITCH_TIME_8MS               2
289 #define DEGLITCH_TIME_16MS              3
290 #define DEGLITCH_TIME_40MS              4
291 #define DEGLITCH_TIME_50MS              5
292 #define DEGLITCH_TIME_60MS              6
293 #define DEGLITCH_TIME_128MS             7
294
295 #define DISC_CTRL3_COMM_IMME            (1<<7)
296 #define DISC_CTRL3_FORCE_MHL            (1<<6)
297 #define DISC_CTRL3_FORCE_USB            (1<<4)
298 #define DISC_CTRL3_USB_EN               (1<<3)
299
300 /* MHL TX DISC4 0x93 Register Bits*/
301 #define CBUS_DISC_PUP_SEL_SHIFT         6
302 #define CBUS_DISC_PUP_SEL_MASK          (3<<CBUS_DISC_PUP_SEL_SHIFT)
303 #define CBUS_DISC_PUP_SEL_10K           (2<<CBUS_DISC_PUP_SEL_SHIFT)
304 #define CBUS_DISC_PUP_SEL_OPEN          (0<<CBUS_DISC_PUP_SEL_SHIFT)
305 #define CBUS_IDLE_PUP_SEL_SHIFT         4
306 #define CBUS_IDLE_PUP_SEL_MASK          (3<<CBUS_IDLE_PUP_SEL_SHIFT)
307 #define CBUS_IDLE_PUP_SEL_OPEN          (0<<CBUS_IDLE_PUP_SEL_SHIFT)
308
309 /* MHL TX DISC5 0x94 Register Bits */
310 #define CBUS_MHL_PUP_SEL_MASK           0x03
311 #define CBUS_MHL_PUP_SEL_5K             0x01
312 #define CBUS_MHL_PUP_SEL_OPEN           0x00
313
314 /* MHL TX DISC6 0x95 Register Bits */
315 #define USB_D_OVR                       (1<<7)
316 #define USB_ID_OVR                      (1<<6)
317 #define DVRFLT_SEL                      (1<<5)
318 #define BLOCK_RGND_INT                  (1<<4)
319 #define SKIP_DEG                        (1<<3)
320 #define CI2CA_POL                       (1<<2)
321 #define CI2CA_WKUP                      (1<<1)
322 #define SINGLE_ATT                      (1<<0)
323
324 /* MHL TX DISC7 0x96 Register Bits
325  *
326  * Bits 7 and 6 are labeled as reserved but seem to be related to toggling
327  * the CBUS signal when generating the wake pulse sequence.
328  */
329 #define USB_D_ODN                       (1<<5)
330 #define VBUS_CHECK                      (1<<2)
331 #define RGND_INTP_MASK                  0x03
332 #define RGND_INTP_OPEN                  0
333 #define RGND_INTP_2K                    1
334 #define RGND_INTP_1K                    2
335 #define RGND_INTP_SHORT                 3
336
337 /* TPI Addr 0x7A Registers */
338 #define TPI_DPD_REG                     0x3D
339
340 #define TPI_PD_TMDS                     (1<<5)
341 #define TPI_PD_OSC_EN                   (1<<4)
342 #define TPI_TCLK_PHASE                  (1<<3)
343 #define TPI_PD_IDCK                     (1<<2)
344 #define TPI_PD_OSC                      (1<<1)
345 #define TPI_PD                          (1<<0)
346
347 /* HDMI RX Registers */
348 #define HDMI_RX_TMDS0_CCTRL1_REG        0x10
349 #define HDMI_RX_TMDS_CLK_EN_REG         0x11
350 #define HDMI_RX_TMDS_CH_EN_REG          0x12
351 #define HDMI_RX_PLL_CALREFSEL_REG       0x17
352 #define HDMI_RX_PLL_VCOCAL_REG          0x1A
353 #define HDMI_RX_EQ_DATA0_REG            0x22
354 #define HDMI_RX_EQ_DATA1_REG            0x23
355 #define HDMI_RX_EQ_DATA2_REG            0x24
356 #define HDMI_RX_EQ_DATA3_REG            0x25
357 #define HDMI_RX_EQ_DATA4_REG            0x26
358 #define HDMI_RX_TMDS_ZONE_CTRL_REG      0x4C
359 #define HDMI_RX_TMDS_MODE_CTRL_REG      0x4D
360
361 #define MHL_DEV_CATEGORY_POW_BIT        (1<<4)
362
363 #define MHL_FEATURE_RCP_SUPPORT         (1<<0)
364 #define MHL_FEATURE_RAP_SUPPORT         (1<<1)
365 #define MHL_FEATURE_SP_SUPPORT          (1<<2)
366
367 #define MHL_STATUS_CLK_MODE_PACKED_PIXEL        0x02
368 #define MHL_STATUS_CLK_MODE_NORMAL      0x03
369
370 #define MHL_STATUS_PATH_ENABLED         0x08
371 #define MHL_STATUS_PATH_DISABLED        0x00
372
373 #define MHL_STATUS_REG_CONNECTED_RDY    0x30
374
375 #define MSC_MAX_QUEUE                   16
376
377 /* page0:0x79 HPD Control Register */
378 #define MHL_HPD_OUT_OVR_EN      (1<<4)
379 #define MHL_HPD_OUT_OVR_VAL     (1<<5)
380
381 #define MHL_DEVCAP_DEV_CAT                      0x02
382 #define MHL_DEVCAP_FEATURE_FLAG         0x0A
383
384 enum page_num {
385         PAGE0 = 0,
386         PAGE1,
387         PAGE2,
388         PAGE3
389 };
390
391 enum rgnd_state {
392         RGND_UNKNOWN = 0,
393         RGND_OPEN,
394         RGND_1K,
395         RGND_2K,
396         RGND_SHORT
397 };
398
399 enum mhl_state {
400         STATE_DISCONNECTED = 0,
401         STATE_DISCOVERY_FAILED,
402         STATE_CBUS_LOCKOUT,
403         STATE_ESTABLISHED,
404 };
405
406 enum msc_subcommand {
407         /* MSC_MSG Sub-Command codes */
408         MSG_RCP =       0x10,
409         MSG_RCPK =      0x11,
410         MSG_RCPE =      0x12,
411         MSG_RAP =       0x20,
412         MSG_RAPK =      0x21,
413 };
414
415 enum cbus_command {
416         CBUS_IDLE =             0x00,
417         CBUS_ACK =              0x33,
418         CBUS_NACK =             0x34,
419         CBUS_ABORT =            0x35,
420         CBUS_WRITE_STAT =       0x60 | 0x80,
421         CBUS_SET_INT =          0x60,
422         CBUS_READ_DEVCAP =      0x61,
423         CBUS_GET_STATE =        0x62,
424         CBUS_GET_VENDOR_ID =    0x63,
425         CBUS_SET_HPD =          0x64,
426         CBUS_CLR_HPD =          0x65,
427         CBUS_SET_CAP_ID =       0x66,
428         CBUS_GET_CAP_ID =       0x67,
429         CBUS_MSC_MSG =          0x68,
430         CBUS_GET_SC1_ERR_CODE = 0x69,
431         CBUS_GET_DDC_ERR_CODE = 0x6A,
432         CBUS_GET_MSC_ERR_CODE = 0x6B,
433         CBUS_WRITE_BURST =      0x6C,
434         CBUS_GET_SC3_ERR_CODE = 0x6D,
435 };
436
437 static struct device *sii9244_mhldev;
438
439 static struct workqueue_struct *sii9234_wq;
440
441 static inline bool mhl_state_is_error(enum mhl_state state)
442 {
443         return state == STATE_DISCOVERY_FAILED ||
444                 state == STATE_CBUS_LOCKOUT;
445 }
446
447 struct msc_packet {
448         enum cbus_command       command;
449         u8      offset;
450         u8      data_1;
451         u8      data_2;
452         bool    sent;
453 };
454
455 struct sii9234_data {
456         struct sii9234_platform_data    *pdata;
457         wait_queue_head_t               wq;
458         struct work_struct              sii9234_int_work;
459
460         bool                            claimed;
461         enum mhl_state                  state;
462         enum rgnd_state                 rgnd;
463         bool                            rsen;
464         atomic_t                        is_callback_scheduled;
465 #ifdef CONFIG_MACH_MIDAS
466         struct wake_lock                wlock;
467 #endif
468         struct mutex                    lock;
469
470         bool                            msc_ready;
471         struct mutex                    msc_lock;
472         struct completion               msc_complete;
473         struct work_struct              msc_work;
474         struct msc_packet               msc_queue[MSC_MAX_QUEUE];
475         int                             msc_front;
476         int                             msc_rear;
477
478         u8                              devcap[16];
479         u8                              link_mode;
480         struct input_dev                *input_dev;
481 };
482
483 static u8 sii9234_tmds_control(struct sii9234_data *sii9234, bool enable);
484 static void __sii9234_power_down(struct sii9234_data *sii9234);
485 static void sii9234_enqueue_msc_work(struct sii9234_data *sii9234, u8 command,
486                 u8 offset, u8 data_1, u8 data_2);
487
488 #ifdef  CONFIG_SAMSUNG_USE_11PIN_CONNECTOR
489 static int is_mhl_cable_connected(void)
490 {
491         return  max77693_muic_get_status1_adc1k_value();
492 }
493 #endif
494
495 static  int mhl_onoff_ex(struct sii9234_data *sii9234, bool onoff)
496 {
497         int ret = 0;
498
499         if (!sii9234 || !sii9234->pdata) {
500                 printk(KERN_ERR "[ERROR]sii9234: %s() getting resource is failed\n",
501                         __func__);
502                 return -ENXIO;
503         }
504
505         mutex_lock(&sii9234->lock);
506         if (sii9234->pdata->power_state == onoff) {
507                 pr_info("sii9234: %s() mhl already %s\n",
508                         __func__, onoff ? "on" : "off");
509                 ret = -ENXIO;
510                 goto exit;
511         } else
512                 pr_info("sii9234: %s(%s)\n", __func__, onoff ? "on" : "off");
513
514         sii9234->pdata->power_state = onoff; /*save power state*/
515
516         if (sii9234->pdata->mhl_sel)
517                 sii9234->pdata->mhl_sel(onoff);
518
519         if (onoff) {
520                 if (sii9234->pdata->hw_onoff)
521                                 sii9234->pdata->hw_onoff(1);
522
523                 if (sii9234->pdata->hw_reset)
524                         sii9234->pdata->hw_reset();
525
526         } else {
527                 pr_info("%s() call __sii9234_power_down\n", __func__);
528
529 #ifdef  CONFIG_SAMSUNG_WORKAROUND_HPD_GLANCE
530                 mhl_hpd_handler(false);
531 #endif
532
533                 __sii9234_power_down(sii9234);
534
535                 if (sii9234->pdata->hw_onoff)
536                         sii9234->pdata->hw_onoff(0);
537                 else
538                         printk(KERN_ERR "[ERROR]sii9234: %s() hw_onoff is NULL\n",
539                                 __func__);
540
541 #ifdef  CONFIG_SAMSUNG_USE_11PIN_CONNECTOR
542                 ret = is_mhl_cable_connected();
543                 if (ret == 1) {
544                         pr_info("sii9234: %s() mhl still inserted, retry discovery\n",
545                                 __func__);
546                         queue_work(sii9234_wq, &(sii9234->sii9234_int_work));
547                 } else if (ret == 0) {
548                         atomic_set(&sii9234->is_callback_scheduled, false);
549                         pr_info("sii9234: %s() mhl cable is removed\n",
550                                         __func__);
551                 } else {
552                         atomic_set(&sii9234->is_callback_scheduled, false);
553                         pr_err("[ERROR] %s() is_mhl_cable_connected error : %d\n",
554                                 __func__, ret);
555                 }
556 #else
557                 atomic_set(&sii9234->is_callback_scheduled, false);
558 #endif
559         }
560
561 exit:
562         mutex_unlock(&sii9234->lock);
563         return ret;
564 }
565
566 static int mhl_tx_write_reg(struct sii9234_data *sii9234, unsigned int offset,
567                 u8 value)
568 {
569         int ret;
570         ret = i2c_smbus_write_byte_data(sii9234->pdata->mhl_tx_client, offset,
571                                         value);
572         if (ret < 0)
573                 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
574                        __LINE__);
575
576         return ret;
577 }
578
579 static int mhl_tx_read_reg(struct sii9234_data *sii9234, unsigned int offset,
580                 u8 *value)
581 {
582         int ret;
583
584         if (!value)
585                 return -EINVAL;
586
587         ret = i2c_smbus_write_byte(sii9234->pdata->mhl_tx_client, offset);
588         if (ret < 0) {
589                 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
590                        __LINE__);
591                 return ret;
592         }
593         ret = i2c_smbus_read_byte(sii9234->pdata->mhl_tx_client);
594         if (ret < 0) {
595                 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
596                        __LINE__);
597                 return ret;
598         }
599         *value = ret & 0x000000FF;
600
601         return 0;
602 }
603
604 static int mhl_tx_set_reg(struct sii9234_data *sii9234, unsigned int offset,
605                 u8 mask)
606 {
607         int ret;
608         u8 value;
609
610         ret = mhl_tx_read_reg(sii9234, offset, &value);
611         if (ret < 0) {
612                 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
613                        __LINE__);
614                 return ret;
615         }
616         value |= mask;
617
618         ret = mhl_tx_write_reg(sii9234, offset, value);
619         if (ret < 0) {
620                 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
621                        __LINE__);
622                 return ret;
623         }
624         return ret;
625 }
626
627 static int mhl_tx_clear_reg(struct sii9234_data *sii9234, unsigned int offset,
628                 u8 mask)
629 {
630         int ret;
631         u8 value;
632
633         ret = mhl_tx_read_reg(sii9234, offset, &value);
634         if (ret < 0) {
635                 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
636                        __LINE__);
637                 return ret;
638         }
639         value &= ~mask;
640
641         ret = mhl_tx_write_reg(sii9234, offset, value);
642         if (ret < 0) {
643                 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
644                        __LINE__);
645                 return ret;
646         }
647         return ret;
648 }
649
650 static int tpi_write_reg(struct sii9234_data *sii9234, unsigned int offset,
651                 u8 value)
652 {
653         int ret;
654         ret = i2c_smbus_write_byte_data(sii9234->pdata->tpi_client, offset,
655                                         value);
656         if (ret < 0)
657                 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
658                        __LINE__);
659
660         return ret;
661 }
662
663 static int tpi_read_reg(struct sii9234_data *sii9234, unsigned int offset,
664                 u8 *value)
665 {
666         int ret;
667
668         if (!value) {
669                 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
670                        __LINE__);
671                 return -EINVAL;
672         }
673
674         ret = i2c_smbus_write_byte(sii9234->pdata->tpi_client, offset);
675         if (ret < 0) {
676                 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
677                        __LINE__);
678                 return ret;
679         }
680         ret = i2c_smbus_read_byte(sii9234->pdata->tpi_client);
681         if (ret < 0) {
682                 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
683                        __LINE__);
684                 return ret;
685         }
686         *value = ret & 0x000000FF;
687
688         return 0;
689 }
690
691 static int hdmi_rx_write_reg(struct sii9234_data *sii9234, unsigned int offset,
692                 u8 value)
693 {
694         int ret;
695         ret = i2c_smbus_write_byte_data(sii9234->pdata->hdmi_rx_client, offset,
696                         value);
697         if (ret < 0) {
698                 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
699                        __LINE__);
700         }
701         return ret;
702 }
703
704 static int hdmi_rx_read_reg(struct sii9234_data *sii9234, unsigned int offset,
705                             u8 *value)
706 {
707         int ret;
708
709         if (!value) {
710                 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
711                        __LINE__);
712                 return -EINVAL;
713         }
714         ret = i2c_smbus_write_byte(sii9234->pdata->hdmi_rx_client, offset);
715         if (ret < 0) {
716                 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
717                        __LINE__);
718                 return ret;
719         }
720         ret = i2c_smbus_read_byte(sii9234->pdata->hdmi_rx_client);
721         if (ret < 0) {
722                 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
723                        __LINE__);
724                 return ret;
725         }
726         *value = ret & 0x000000FF;
727
728         return 0;
729 }
730
731 static int cbus_write_reg(struct sii9234_data *sii9234, unsigned int offset,
732                 u8 value)
733 {
734         int ret;
735         ret = i2c_smbus_write_byte_data(sii9234->pdata->cbus_client, offset,
736                                         value);
737         if (ret < 0)
738                 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
739                        __LINE__);
740
741         return ret;
742 }
743
744 static int cbus_read_reg(struct sii9234_data *sii9234, unsigned int offset,
745                 u8 *value)
746 {
747         int ret;
748
749         if (!value) {
750                 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
751                        __LINE__);
752                 return -EINVAL;
753         }
754         ret = i2c_smbus_write_byte(sii9234->pdata->cbus_client, offset);
755         if (ret < 0) {
756                 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
757                        __LINE__);
758                 return ret;
759         }
760         ret = i2c_smbus_read_byte(sii9234->pdata->cbus_client);
761         if (ret < 0) {
762                 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
763                        __LINE__);
764                 return ret;
765         }
766         *value = ret & 0x000000FF;
767
768         return 0;
769 }
770
771 static int cbus_set_reg(struct sii9234_data *sii9234, unsigned int offset,
772                 u8 mask)
773 {
774         int ret;
775         u8 value;
776
777         ret = cbus_read_reg(sii9234, offset, &value);
778         if (ret < 0) {
779                 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
780                        __LINE__);
781                 return ret;
782         }
783         value |= mask;
784
785         ret = cbus_write_reg(sii9234, offset, value);
786         if (ret < 0) {
787                 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
788                        __LINE__);
789                 return ret;
790         }
791         return ret;
792 }
793
794 static int mhl_wake_toggle(struct sii9234_data *sii9234,
795                 unsigned long high_period,
796                 unsigned long low_period)
797 {
798         int ret;
799
800         /* These bits are not documented. */
801         ret =
802             mhl_tx_set_reg(sii9234, MHL_TX_DISC_CTRL7_REG, (1<<7) | (1<<6));
803         if (ret < 0) {
804                 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
805                        __LINE__);
806                 return ret;
807         }
808
809         usleep_range(high_period * USEC_PER_MSEC, high_period * USEC_PER_MSEC);
810
811         ret =
812             mhl_tx_clear_reg(sii9234, MHL_TX_DISC_CTRL7_REG, (1<<7) | (1<<6));
813         if (ret < 0) {
814                 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
815                        __LINE__);
816                 return ret;
817         }
818
819         usleep_range(low_period * USEC_PER_MSEC, low_period * USEC_PER_MSEC);
820
821         return 0;
822 }
823
824 static int mhl_send_wake_pulses(struct sii9234_data *sii9234)
825 {
826         int ret;
827
828         ret = mhl_wake_toggle(sii9234, T_SRC_WAKE_PULSE_WIDTH_1,
829                         T_SRC_WAKE_PULSE_WIDTH_1);
830         if (ret < 0) {
831                 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
832                        __LINE__);
833                 return ret;
834         }
835
836         ret = mhl_wake_toggle(sii9234, T_SRC_WAKE_PULSE_WIDTH_1,
837                         T_SRC_WAKE_PULSE_WIDTH_2);
838         if (ret < 0) {
839                 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
840                        __LINE__);
841                 return ret;
842         }
843
844         ret = mhl_wake_toggle(sii9234, T_SRC_WAKE_PULSE_WIDTH_1,
845                         T_SRC_WAKE_PULSE_WIDTH_1);
846         if (ret < 0) {
847                 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
848                        __LINE__);
849                 return ret;
850         }
851
852         ret = mhl_wake_toggle(sii9234, T_SRC_WAKE_PULSE_WIDTH_1,
853                               T_SRC_WAKE_TO_DISCOVER);
854         if (ret < 0) {
855                 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
856                        __LINE__);
857                 return ret;
858         }
859
860         return 0;
861 }
862
863 static int sii9234_cbus_reset(struct sii9234_data *sii9234)
864 {
865         int ret;
866         int idx;
867
868         /* Reset CBUS */
869         ret = mhl_tx_set_reg(sii9234, MHL_TX_SRST, 0x03);
870         if (ret < 0)
871                 return ret;
872
873         usleep_range(2000, 3000);
874
875         ret = mhl_tx_clear_reg(sii9234, MHL_TX_SRST, 0x03);
876         if (ret < 0)
877                 return ret;
878
879         for (idx = 0 ; idx < 4 ; idx++) {
880                 cbus_write_reg(sii9234, 0xE0 + idx, 0xFF);
881                 cbus_write_reg(sii9234, 0xF0 + idx, 0xFF);
882         }
883
884         /* Adjust interrupt mask everytime reset is performed.*/
885         ret = cbus_write_reg(sii9234, CBUS_INT_1_MASK, 0);
886         if (ret < 0) {
887                 printk(KERN_ERR "[ERROR] %s() write CBUS_INTR1_ENABLE_REG fail\n",
888                         __func__);
889                 return ret;
890         }
891
892         ret = cbus_write_reg(sii9234, CBUS_INT_2_MASK, 0);
893         if (ret < 0) {
894                 printk(KERN_ERR "[ERROR] %s() write CBUS_INTR2_ENABLE_REG fail\n",
895                         __func__);
896                 return ret;
897         }
898
899         return 0;
900 }
901
902 /* require to chek mhl imformation of samsung in cbus_init_register*/
903 static int sii9234_cbus_init(struct sii9234_data *sii9234)
904 {
905         u8 value;
906
907         pr_debug("%s()\n", __func__);
908         cbus_write_reg(sii9234, 0x07, 0xF2);
909
910         cbus_write_reg(sii9234, 0x40, 0x03);
911         cbus_write_reg(sii9234, 0x42, 0x06);
912         cbus_write_reg(sii9234, 0x36, 0x0C);
913         cbus_write_reg(sii9234, 0x3D, 0xFD);
914
915         cbus_write_reg(sii9234, 0x1C, 0x01);
916         cbus_write_reg(sii9234, 0x1D, 0x0F);
917
918         cbus_write_reg(sii9234, 0x44, 0x02);
919
920         cbus_write_reg(sii9234, 0x31, 0x0D);
921         cbus_write_reg(sii9234, 0x22, 0x01);
922         cbus_write_reg(sii9234, 0x30, 0x01);
923
924         /* Setup our devcap*/
925         cbus_write_reg(sii9234, 0x80, 0x00);/*To meet cts 6.3.10.1 spec*/
926
927         cbus_write_reg(sii9234, 0x81, 0x11);
928         cbus_write_reg(sii9234, 0x82, 0x02);
929         cbus_write_reg(sii9234, 0x83, 0);
930         cbus_write_reg(sii9234, 0x84, 0);
931         cbus_write_reg(sii9234, 0x85, 0x24);
932         cbus_write_reg(sii9234, 0x86, 0x01);
933         cbus_write_reg(sii9234, 0x87, 0);
934         cbus_write_reg(sii9234, 0x88, 1<<7);
935         cbus_write_reg(sii9234, 0x89, 0x0F);
936         cbus_write_reg(sii9234, 0x8A, (1<<0) | (1<<1) | (1<<2));
937         cbus_write_reg(sii9234, 0x8B, 0);
938         cbus_write_reg(sii9234, 0x8C, 0);
939         cbus_write_reg(sii9234, 0x8D, 16);
940         cbus_write_reg(sii9234, 0x8E, 0x33);
941         cbus_write_reg(sii9234, 0x8F, 0);
942
943         cbus_read_reg(sii9234, 0x31, &value);
944         value |= 0x0C;
945         cbus_write_reg(sii9234, 0x31, value);
946
947         cbus_write_reg(sii9234, 0x30, 0x01);
948
949         cbus_read_reg(sii9234, 0x3C, &value);
950         value &= ~0x38;
951         value |= 0x30;
952         cbus_write_reg(sii9234, 0x3C, value);
953
954         cbus_read_reg(sii9234, 0x22, &value);
955         value &= ~0x0F;
956         value |= 0x0D;
957         cbus_write_reg(sii9234, 0x22, value);
958
959         cbus_read_reg(sii9234, 0x2E, &value);
960         value |= 0x15;
961         cbus_write_reg(sii9234, 0x2E, value);
962
963         cbus_write_reg(sii9234, CBUS_INT_1_MASK, 0);
964         cbus_write_reg(sii9234, CBUS_INT_2_MASK, 0);
965
966         return 0;
967 }
968
969 static void force_usb_id_switch_open(struct sii9234_data *sii9234)
970 {
971         pr_debug("sii9234: %s() open usb_id\n", __func__);
972         /*Disable CBUS discovery*/
973         mhl_tx_clear_reg(sii9234, MHL_TX_DISC_CTRL1_REG, (1<<0));
974         /*Force USB ID switch to open*/
975         mhl_tx_set_reg(sii9234, MHL_TX_DISC_CTRL6_REG, USB_ID_OVR);
976
977         /* siliconimage recommanded value is 0xA6 But make detection error */
978 /*      mhl_tx_set_reg(sii9234, MHL_TX_DISC_CTRL3_REG, 0x86);*/
979         mhl_tx_set_reg(sii9234, MHL_TX_DISC_CTRL3_REG, 0xA6);
980         /*Force upstream HPD to 0 when not in MHL mode.*/
981         mhl_tx_clear_reg(sii9234, MHL_TX_INT_CTRL_REG, (1<<5));
982         mhl_tx_set_reg(sii9234, MHL_TX_INT_CTRL_REG, (1<<4));
983 }
984
985 static void release_usb_id_switch_open(struct sii9234_data *sii9234)
986 {
987         usleep_range(T_SRC_CBUS_FLOAT * USEC_PER_MSEC,
988                         T_SRC_CBUS_FLOAT * USEC_PER_MSEC);
989         pr_debug("sii9234: %s() release usb_id\n", __func__);
990         /* clear USB ID switch to open*/
991         mhl_tx_clear_reg(sii9234, MHL_TX_DISC_CTRL6_REG, USB_ID_OVR);
992
993         /* Enable CBUS discovery*/
994         mhl_tx_set_reg(sii9234, MHL_TX_DISC_CTRL1_REG, (1<<0));
995 }
996
997 #ifdef CONFIG_SII9234_CBUS
998 static void cbus_req_abort_error(struct sii9234_data *sii9234)
999 {
1000         u8 abort_reason = 0;
1001
1002         pr_debug("sii9234: %s() MSC Request Aborted:", __func__);
1003
1004         cbus_read_reg(sii9234, MSC_REQ_ABORT_REASON_REG, &abort_reason);
1005         cbus_write_reg(sii9234, MSC_REQ_ABORT_REASON_REG, 0xff);
1006
1007         if (abort_reason) {
1008                 if (abort_reason & ABORT_BY_PEER)
1009                         pr_cont(" Peer Sent an ABORT");
1010                 if (abort_reason & UNDEF_CMD)
1011                         pr_cont(" Undefined Opcode");
1012                 if (abort_reason & TIMEOUT)
1013                         pr_cont(" Requestor Translation layer Timeout");
1014                 if (abort_reason & PROTO_ERROR)
1015                         pr_cont(" Protocol Error");
1016                 if (abort_reason & MAX_FAIL) {
1017                         u8 msc_retry_thr_val = 0;
1018                         pr_cont(" Retry Threshold exceeded");
1019                         cbus_read_reg(sii9234,
1020                                         MSC_RETRY_FAIL_LIM_REG,
1021                                         &msc_retry_thr_val);
1022                         pr_cont("Retry Threshold value is:%d",
1023                                         msc_retry_thr_val);
1024                 }
1025         }
1026         pr_cont("\n");
1027 }
1028
1029 static void cbus_resp_abort_error(struct sii9234_data *sii9234)
1030 {
1031         u8 abort_reason = 0;
1032
1033         pr_debug("sii9234: %s() MSC Response Aborted:", __func__);
1034         cbus_read_reg(sii9234, MSC_RESP_ABORT_REASON_REG, &abort_reason);
1035         cbus_write_reg(sii9234, MSC_RESP_ABORT_REASON_REG, 0xFF);
1036
1037         if (abort_reason) {
1038                 if (abort_reason & ABORT_BY_PEER)
1039                         pr_cont(" Peer Sent an ABORT");
1040                 if (abort_reason & UNDEF_CMD)
1041                         pr_cont(" Undefined Opcode");
1042                 if (abort_reason & TIMEOUT)
1043                         pr_cont(" Requestor Translation layer Timeout");
1044         }
1045                 pr_cont("\n");
1046 }
1047
1048 static bool cbus_ddc_abort_error(struct sii9234_data *sii9234)
1049 {
1050         u8 val1, val2;
1051
1052         /* clear the ddc abort counter */
1053         cbus_write_reg(sii9234, 0x29, 0xFF);
1054         cbus_read_reg(sii9234, 0x29, &val1);
1055         usleep_range(3000, 4000);
1056         cbus_read_reg(sii9234, 0x29, &val2);
1057         if (val2 > (val1 + 50)) {
1058                 pr_debug("sii9234: %s() Applying DDC Abort Safety(SWA18958)\n",
1059                                 __func__);
1060                 mhl_tx_set_reg(sii9234, MHL_TX_SRST, (1<<3));
1061                 mhl_tx_clear_reg(sii9234, MHL_TX_SRST, (1<<3));
1062                 force_usb_id_switch_open(sii9234);
1063                 release_usb_id_switch_open(sii9234);
1064                 mhl_tx_write_reg(sii9234, MHL_TX_MHLTX_CTL1_REG, 0xD0);
1065                 sii9234_tmds_control(sii9234, false);
1066                 /* Disconnect and notify to OTG */
1067                 return true;
1068         }
1069         pr_debug("sii9234: %s() DDC abort interrupt\n", __func__);
1070
1071         return false;
1072 }
1073
1074 #ifdef CONFIG_SII9234_RCP
1075 static void rcp_key_report(struct sii9234_data *sii9234, u8 key)
1076 {
1077         pr_debug("sii9234: %s(): report rcp key: %d\n", __func__, key);
1078         input_report_key(sii9234->input_dev, (unsigned int)key + 1, 1);
1079         input_report_key(sii9234->input_dev, (unsigned int)key + 1, 0);
1080         input_sync(sii9234->input_dev);
1081 }
1082
1083 static void cbus_process_rcp_key(struct sii9234_data *sii9234, u8 key)
1084 {
1085         u8 offset, data_2 = 0;
1086
1087         if (code[key].valid) {
1088                 /* Report the key */
1089                 rcp_key_report(sii9234, key);
1090                 offset = MSG_RCPK;
1091         } else {
1092                 /*
1093                 * Send a RCPE(RCP Error Message) to Peer followed by
1094                 * RCPK with old key-code so that initiator(TV) can
1095                 * recognize failed key code.error code = 0x01 means
1096                 * Ineffective key code was received.
1097                 * See Table 21.(PRM)for details.
1098                 */
1099                 offset = MSG_RCPE;
1100                 data_2 = 0x01;
1101         }
1102
1103         sii9234_enqueue_msc_work(sii9234, CBUS_MSC_MSG, offset, key, data_2);
1104 }
1105
1106 static void cbus_process_rap_key(struct sii9234_data *sii9234, u8 key)
1107 {
1108         if (CBUS_MSC_RAP_CONTENT_ON == key)
1109                 sii9234_tmds_control(sii9234, true);
1110         else if (CBUS_MSC_RAP_CONTENT_OFF == key)
1111                 sii9234_tmds_control(sii9234, false);
1112
1113         sii9234_enqueue_msc_work(sii9234, CBUS_MSC_MSG, MSG_RAPK, 0x0, 0x0);
1114 }
1115
1116 /*
1117  * Incoming MSC_MSG : RCP/RAP/RCPK/RCPE/RAPK commands
1118  *
1119  * Process RCP key codes and the send supported keys to userspace.
1120  * If a key is not supported then an error ack is sent to the peer.  Note
1121  * that by default all key codes are supported.
1122  *
1123  * An alternate method might be to decide the validity of the key in the
1124  * driver itself.  However, the driver does not have any criteria to which
1125  * to make this decision.
1126  */
1127 static void cbus_handle_msc_msg(struct sii9234_data *sii9234)
1128 {
1129         u8 cmd_code, key;
1130
1131         if (sii9234->state != STATE_ESTABLISHED) {
1132                 pr_debug("sii9234: %s(): invalid MHL state\n", __func__);
1133                 return;
1134         }
1135
1136         cbus_read_reg(sii9234, CBUS_MSC_MSG_CMD_IN, &cmd_code);
1137         cbus_read_reg(sii9234, CBUS_MSC_MSG_DATA_IN, &key);
1138
1139         pr_debug("sii9234: %s(): cmd_code:%d, key:%d\n", __func__,
1140                         cmd_code, key);
1141
1142         switch (cmd_code) {
1143         case MSG_RCP:
1144                 pr_debug("sii9234: %s(): RCP Arrived. KEY CODE:%d\n",
1145                                 __func__, key);
1146                 cbus_process_rcp_key(sii9234, key);
1147                 break;
1148         case MSG_RAP:
1149                 pr_debug("sii9234: %s(): RAP Arrived\n", __func__);
1150                 cbus_process_rap_key(sii9234, key);
1151                 break;
1152         case MSG_RCPK:
1153                 pr_debug("sii9234: %s(): RCPK Arrived\n", __func__);
1154                 break;
1155         case MSG_RCPE:
1156                 pr_debug("sii9234: %s(): RCPE Arrived\n", __func__);
1157                 break;
1158         case MSG_RAPK:
1159                 pr_debug("sii9234: %s(): RAPK Arrived\n", __func__);
1160                 break;
1161         default:
1162                 pr_debug("sii9234: %s(): MAC error\n", __func__);
1163                 sii9234_enqueue_msc_work(sii9234, CBUS_GET_MSC_ERR_CODE,
1164                                                                 0x0, 0x0, 0x0);
1165                 break;
1166         }
1167 }
1168 #endif  /* CONFIG_SII9234_RCP */
1169
1170 void mhl_path_enable(struct sii9234_data *sii9234, bool path_en)
1171 {
1172         pr_debug("sii9234: %s(): mhl_path_enable MHL_STATUS_PATH %s\n",
1173                                 __func__, path_en ? "ENABLED" : "DISABLED");
1174
1175         if (path_en)
1176                 sii9234->link_mode |= MHL_STATUS_PATH_ENABLED;
1177         else
1178                 sii9234->link_mode &= ~MHL_STATUS_PATH_ENABLED;
1179
1180         sii9234_enqueue_msc_work(sii9234, CBUS_WRITE_STAT,
1181                         CBUS_LINK_CONTROL_2_REG, sii9234->link_mode, 0x0);
1182 }
1183
1184 static void cbus_handle_wrt_stat_recd(struct sii9234_data *sii9234)
1185 {
1186         u8 status_reg0, status_reg1;
1187
1188         pr_debug("sii9234: %s(): CBUS WRT_STAT_RECD\n", __func__);
1189
1190         /*
1191         * The two MHL status registers need to read to ensure that the MSC is
1192         * ready to receive the READ_DEVCAP command.
1193         * The READ_DEVCAP command is need to determine the dongle power state
1194         * and whether RCP, RCPE, RCPK, RAP, and RAPE are supported.
1195         *
1196         * Note that this is not documented properly in the PRM.
1197         */
1198
1199         cbus_read_reg(sii9234, CBUS_MHL_STATUS_REG_0, &status_reg0);
1200         cbus_write_reg(sii9234, CBUS_MHL_STATUS_REG_0, 0xFF);
1201
1202         cbus_read_reg(sii9234, CBUS_MHL_STATUS_REG_1, &status_reg1);
1203         cbus_write_reg(sii9234, CBUS_MHL_STATUS_REG_1, 0xFF);
1204
1205         pr_debug("sii9234: %s(): STATUS_REG0 : [%d];STATUS_REG1 : [%d]\n",
1206                         __func__, status_reg0, status_reg1);
1207
1208         if (!(sii9234->link_mode & MHL_STATUS_PATH_ENABLED) &&
1209                                 (MHL_STATUS_PATH_ENABLED & status_reg1)) {
1210                 mhl_path_enable(sii9234, true);
1211         } else if ((sii9234->link_mode & MHL_STATUS_PATH_ENABLED) &&
1212                                 !(MHL_STATUS_PATH_ENABLED & status_reg1)) {
1213                 mhl_path_enable(sii9234, false);
1214         }
1215
1216         if (status_reg0 & MHL_STATUS_DCAP_READY) {
1217                 pr_debug("sii9234: %s(): DEV CAP READY\n", __func__);
1218
1219                 sii9234->msc_ready = true;
1220
1221                 pr_debug("sii9234: %s(): DEV CAP READY dev cat\n", __func__);
1222                 sii9234_enqueue_msc_work(sii9234, CBUS_READ_DEVCAP,
1223                                         MHL_DEVCAP_DEV_CAT, 0x0, 0x0);
1224
1225                 pr_debug("sii9234: %s(): DEV CAP READY feature flag\n",
1226                                 __func__);
1227                 sii9234_enqueue_msc_work(sii9234, CBUS_READ_DEVCAP,
1228                                         MHL_DEVCAP_FEATURE_FLAG, 0x0, 0x0);
1229         }
1230 }
1231
1232 static void cbus_handle_edid_change(struct sii9234_data *sii9234)
1233 {
1234                 /* Enable Overriding HPD OUT */
1235                 mhl_tx_set_reg(sii9234, MHL_TX_INT_CTRL_REG, (1<<4));
1236
1237                 /*
1238                  * As per HDMI specification to indicate EDID change
1239                  * in TV (or sink), we need to toggle HPD line.
1240                  */
1241
1242                 /* HPD OUT = Low */
1243                 mhl_tx_clear_reg(sii9234, MHL_TX_INT_CTRL_REG, (1<<5));
1244
1245                 /* A SET_HPD command shall not follow a CLR_HPD command
1246                  * within less than THPD_WIDTH(50ms).
1247                  */
1248                 msleep(T_HPD_WIDTH);
1249
1250                 /* HPD OUT = High */
1251                 mhl_tx_set_reg(sii9234, MHL_TX_INT_CTRL_REG, (1<<5));
1252
1253                 /* Disable Overriding of HPD OUT */
1254                 mhl_tx_clear_reg(sii9234, MHL_TX_INT_CTRL_REG, (1<<4));
1255 }
1256
1257 static void cbus_handle_set_int_recd(struct sii9234_data *sii9234)
1258 {
1259         u8 intr_reg0, intr_reg1, value;
1260
1261         /* read and clear interrupt*/
1262         cbus_read_reg(sii9234, CBUS_MHL_INTR_REG_0, &intr_reg0);
1263         cbus_write_reg(sii9234, CBUS_MHL_INTR_REG_0, intr_reg0);
1264
1265         cbus_read_reg(sii9234, CBUS_MHL_INTR_REG_1, &intr_reg1);
1266         cbus_write_reg(sii9234, CBUS_MHL_INTR_REG_1, intr_reg1);
1267
1268         cbus_read_reg(sii9234, CBUS_MHL_INTR_REG_2, &value);
1269         cbus_write_reg(sii9234, CBUS_MHL_INTR_REG_2, value);
1270
1271         cbus_read_reg(sii9234, CBUS_MHL_INTR_REG_3, &value);
1272         cbus_write_reg(sii9234, CBUS_MHL_INTR_REG_3, value);
1273
1274         pr_debug("sii9234: %s(): INTR_REG0 : [%d]; INTR_REG1 : [%d]\n",
1275                         __func__, intr_reg0, intr_reg1);
1276
1277         if (intr_reg0 & MHL_INT_DCAP_CHG) {
1278                 pr_debug("sii9234: %s(): IHL_INT_DCAP_CHG\n", __func__);
1279
1280                 sii9234_enqueue_msc_work(sii9234, CBUS_READ_DEVCAP,
1281                                         MHL_DEVCAP_DEV_CAT, 0x0, 0x0);
1282
1283                 sii9234_enqueue_msc_work(sii9234, CBUS_READ_DEVCAP,
1284                                         MHL_DEVCAP_FEATURE_FLAG, 0x0, 0x0);
1285         }
1286
1287         if (intr_reg0 & MHL_INT_DSCR_CHG)
1288                 pr_debug("sii9234: %s(): IHL_INT_DSCR_CHG\n", __func__);
1289
1290         if (intr_reg0 & MHL_INT_REQ_WRT) {
1291                 pr_debug("sii9234: %s(): MHL_INT_REQ_WRT\n", __func__);
1292
1293                 sii9234_enqueue_msc_work(sii9234, CBUS_SET_INT,
1294                                         MHL_RCHANGE_INT, MHL_INT_GRT_WRT, 0x0);
1295         }
1296
1297         if (intr_reg0 & MHL_INT_GRT_WRT)
1298                 pr_debug("sii9234: %s(): MHL_INT_GRT_WRT\n", __func__);
1299
1300         if (intr_reg1 & MHL_INT_EDID_CHG) {
1301                 pr_debug("sii9234: %s(): MHL_INT_EDID_CHG\n", __func__);
1302                 cbus_handle_edid_change(sii9234);
1303         }
1304 }
1305 #endif /* CONFIG_SII9234_CBUS */
1306
1307 static int sii9234_power_init(struct sii9234_data *sii9234)
1308 {
1309         int ret;
1310
1311         /* Force the SiI9234 into the D0 state. */
1312         ret = tpi_write_reg(sii9234, TPI_DPD_REG, 0x3F);
1313         if (ret < 0) {
1314                 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1315                        __LINE__);
1316                 return ret;
1317         }
1318
1319         /* Enable TxPLL Clock */
1320         ret = hdmi_rx_write_reg(sii9234, HDMI_RX_TMDS_CLK_EN_REG, 0x01);
1321         if (ret < 0) {
1322                 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1323                        __LINE__);
1324                 return ret;
1325         }
1326
1327         /* Enable Tx Clock Path & Equalizer */
1328         ret = hdmi_rx_write_reg(sii9234, HDMI_RX_TMDS_CH_EN_REG, 0x15);
1329         if (ret < 0) {
1330                 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1331                        __LINE__);
1332                 return ret;
1333         }
1334
1335         /* Power Up TMDS */
1336         ret = mhl_tx_write_reg(sii9234, 0x08, 0x35);
1337         if (ret < 0) {
1338                 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1339                        __LINE__);
1340                 return ret;
1341         }
1342
1343         return 0;
1344 }
1345
1346 static int sii9234_hdmi_init(struct sii9234_data *sii9234)
1347 {
1348         int ret;
1349         /* Analog PLL Control
1350          * bits 5:4 = 2b00 as per characterization team.
1351          */
1352         ret = hdmi_rx_write_reg(sii9234, HDMI_RX_TMDS0_CCTRL1_REG, 0xC1);
1353         if (ret < 0) {
1354                 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1355                        __LINE__);
1356                 return ret;
1357         }
1358
1359         /* PLL Calrefsel */
1360         ret = hdmi_rx_write_reg(sii9234, HDMI_RX_PLL_CALREFSEL_REG, 0x03);
1361         if (ret < 0) {
1362                 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1363                        __LINE__);
1364                 return ret;
1365         }
1366
1367         /* VCO Cal */
1368         ret = hdmi_rx_write_reg(sii9234, HDMI_RX_PLL_VCOCAL_REG, 0x20);
1369         if (ret < 0) {
1370                 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1371                        __LINE__);
1372                 return ret;
1373         }
1374
1375         /* Auto EQ */
1376         ret = hdmi_rx_write_reg(sii9234, HDMI_RX_EQ_DATA0_REG, 0x8A);
1377         if (ret < 0) {
1378                 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1379                        __LINE__);
1380                 return ret;
1381         }
1382
1383         /* Auto EQ */
1384         ret = hdmi_rx_write_reg(sii9234, HDMI_RX_EQ_DATA1_REG, 0x6A);
1385         if (ret < 0) {
1386                 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1387                        __LINE__);
1388                 return ret;
1389         }
1390
1391         /* Auto EQ */
1392         ret = hdmi_rx_write_reg(sii9234, HDMI_RX_EQ_DATA2_REG, 0xAA);
1393         if (ret < 0) {
1394                 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1395                        __LINE__);
1396                 return ret;
1397         }
1398
1399         /* Auto EQ */
1400         ret = hdmi_rx_write_reg(sii9234, HDMI_RX_EQ_DATA3_REG, 0xCA);
1401         if (ret < 0) {
1402                 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1403                        __LINE__);
1404                 return ret;
1405         }
1406
1407         /* Auto EQ */
1408         ret = hdmi_rx_write_reg(sii9234, HDMI_RX_EQ_DATA4_REG, 0xEA);
1409         if (ret < 0) {
1410                 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1411                        __LINE__);
1412                 return ret;
1413         }
1414
1415         /* Manual zone */
1416         ret = hdmi_rx_write_reg(sii9234, HDMI_RX_TMDS_ZONE_CTRL_REG, 0xA0);
1417         if (ret < 0) {
1418                 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1419                        __LINE__);
1420                 return ret;
1421         }
1422
1423         /* PLL Mode Value */
1424         ret = hdmi_rx_write_reg(sii9234, HDMI_RX_TMDS_MODE_CTRL_REG, 0x00);
1425         if (ret < 0) {
1426                 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1427                        __LINE__);
1428                 return ret;
1429         }
1430
1431 /* need to test */
1432 /*      ret = mhl_tx_write_reg(sii9234, MHL_TX_TMDS_CCTRL, 0x34); */
1433         ret = mhl_tx_write_reg(sii9234, MHL_TX_TMDS_CCTRL, 0x24);
1434         if (ret < 0) {
1435                 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1436                        __LINE__);
1437                 return ret;
1438         }
1439
1440         ret = hdmi_rx_write_reg(sii9234, 0x45, 0x44);
1441         if (ret < 0) {
1442                 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1443                        __LINE__);
1444                 return ret;
1445         }
1446
1447         /* Rx PLL BW ~ 4MHz */
1448         ret = hdmi_rx_write_reg(sii9234, 0x31, 0x0A);
1449         if (ret < 0) {
1450                 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1451                        __LINE__);
1452                 return ret;
1453         }
1454
1455         /* Analog PLL Control
1456          * bits 5:4 = 2b00 as per characterization team.
1457          */
1458         return 0;
1459 }
1460
1461 static int sii9234_mhl_tx_ctl_int(struct sii9234_data *sii9234)
1462 {
1463         int ret;
1464
1465         ret = mhl_tx_write_reg(sii9234, MHL_TX_MHLTX_CTL1_REG, 0xD0);
1466         if (ret < 0) {
1467                 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1468                        __LINE__);
1469                 return ret;
1470         }
1471
1472         ret = mhl_tx_write_reg(sii9234, MHL_TX_MHLTX_CTL2_REG, 0xFC);
1473         if (ret < 0) {
1474                 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1475                        __LINE__);
1476                 return ret;
1477         }
1478
1479         ret = mhl_tx_write_reg(sii9234, MHL_TX_MHLTX_CTL4_REG, 0xEB);
1480         if (ret < 0) {
1481                 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1482                        __LINE__);
1483                 return ret;
1484         }
1485
1486         ret = mhl_tx_write_reg(sii9234, MHL_TX_MHLTX_CTL7_REG, 0x0C);
1487         if (ret < 0) {
1488                 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1489                        __LINE__);
1490                 return ret;
1491         }
1492
1493         return 0;
1494 }
1495
1496 static void __sii9234_power_down(struct sii9234_data *sii9234)
1497 {
1498         disable_irq_nosync(sii9234->pdata->mhl_tx_client->irq);
1499
1500         if (sii9234->claimed) {
1501                 if (sii9234->pdata->vbus_present)
1502                         sii9234->pdata->vbus_present(false);
1503         }
1504
1505         sii9234->state = STATE_DISCONNECTED;
1506         sii9234->claimed = false;
1507
1508         /* power down mhl intenal modules */
1509         tpi_write_reg(sii9234, TPI_DPD_REG, 0);
1510 }
1511
1512 /* Must call with sii9234->lock held */
1513 static int sii9234_msc_req_locked(struct sii9234_data *sii9234,
1514                                         struct msc_packet *msc_pkt)
1515 {
1516         int ret;
1517         u8 start_command;
1518
1519         if (sii9234->state != STATE_ESTABLISHED)
1520                 return -ENOENT;
1521
1522         init_completion(&sii9234->msc_complete);
1523
1524         cbus_write_reg(sii9234, CBUS_MSC_OFFSET_REG, msc_pkt->offset);
1525         cbus_write_reg(sii9234, CBUS_MSC_FIRST_DATA_OUT, msc_pkt->data_1);
1526
1527         switch (msc_pkt->command) {
1528         case CBUS_SET_INT:
1529         case CBUS_WRITE_STAT:
1530                 start_command = START_WRITE_STAT_INT;
1531                 break;
1532         case CBUS_MSC_MSG:
1533                 cbus_write_reg(sii9234, CBUS_MSC_SECOND_DATA_OUT,
1534                                                         msc_pkt->data_2);
1535                 cbus_write_reg(sii9234, CBUS_MSC_OFFSET_REG, msc_pkt->command);
1536
1537                 start_command = START_MSC_MSG;
1538                 break;
1539         case CBUS_READ_DEVCAP:
1540                 start_command = START_READ_DEVCAP;
1541                 break;
1542         case CBUS_WRITE_BURST:
1543                 start_command = START_WRITE_BURST;
1544                 break;
1545         case CBUS_GET_STATE:
1546         case CBUS_GET_VENDOR_ID:
1547         case CBUS_SET_HPD:
1548         case CBUS_CLR_HPD:
1549         case CBUS_GET_MSC_ERR_CODE:
1550         case CBUS_GET_SC3_ERR_CODE:
1551         case CBUS_GET_SC1_ERR_CODE:
1552         case CBUS_GET_DDC_ERR_CODE:
1553                 cbus_write_reg(sii9234, CBUS_MSC_OFFSET_REG, msc_pkt->command);
1554
1555                 start_command = START_MSC_RESERVED;
1556                 break;
1557         default:
1558                 pr_info("%s() invalid msc command(%d)\n",
1559                         __func__, msc_pkt->command);
1560                 return -EINVAL;
1561         }
1562
1563         cbus_write_reg(sii9234, CBUS_MSC_COMMAND_START, start_command);
1564
1565         mutex_unlock(&sii9234->lock);
1566         ret = wait_for_completion_timeout(&sii9234->msc_complete,
1567                                           msecs_to_jiffies(500));
1568         if (ret == 0)
1569                 printk(KERN_ERR "[ERROR] %s() MSC_REQ_DONE timeout\n",
1570                         __func__);
1571
1572         mutex_lock(&sii9234->lock);
1573
1574         return ret ? 0 : -EIO;
1575 }
1576
1577 void sii9234_process_msc_work(struct work_struct *work)
1578 {
1579         struct msc_packet msc_pkt;
1580         u8 val;
1581         int ret;
1582         struct sii9234_data *sii9234 = container_of(work,
1583                                                 struct sii9234_data,
1584                                                 msc_work);
1585
1586         mutex_lock(&sii9234->msc_lock);
1587         mutex_lock(&sii9234->lock);
1588
1589         pr_info("%s()\n", __func__);
1590
1591         if (!sii9234->msc_queue[sii9234->msc_front].sent) {
1592
1593                 msc_pkt.command
1594                         = sii9234->msc_queue[sii9234->msc_front].command;
1595                 msc_pkt.offset = sii9234->msc_queue[sii9234->msc_front].offset;
1596                 msc_pkt.data_1 = sii9234->msc_queue[sii9234->msc_front].data_1;
1597                 msc_pkt.data_2 = sii9234->msc_queue[sii9234->msc_front].data_2;
1598
1599                 sii9234->msc_queue[sii9234->msc_front].sent = true;
1600
1601                 /* msc request */
1602                 ret = sii9234_msc_req_locked(sii9234, &msc_pkt);
1603                 if (ret < 0) {
1604                         pr_info("%s(): msc_req_locked error %d\n", __func__,
1605                                         ret);
1606                         goto exit;
1607                 }
1608
1609                 /* MSC_REQ_DONE received */
1610                 switch (msc_pkt.command) {
1611                 case CBUS_MSC_MSG:
1612                         if (msc_pkt.offset == MSG_RCPE &&
1613                                                 msc_pkt.data_2 == 0x01) {
1614                                 sii9234_enqueue_msc_work(sii9234, CBUS_MSC_MSG,
1615                                                 MSG_RCPK, msc_pkt.data_1, 0x0);
1616                         }
1617                         break;
1618                 case CBUS_WRITE_STAT:
1619                         break;
1620                 case CBUS_SET_INT:
1621                         break;
1622                 case CBUS_WRITE_BURST:
1623                         break;
1624                 case CBUS_READ_DEVCAP:
1625                         ret = cbus_read_reg(sii9234,
1626                                         CBUS_MSC_FIRST_DATA_IN, &val);
1627                         if (ret < 0)
1628                                 break;
1629
1630                         sii9234->devcap[msc_pkt.offset] = val;
1631                         break;
1632                 default:
1633                         break;
1634                 }
1635         }
1636 exit:
1637         mutex_unlock(&sii9234->lock);
1638
1639         sii9234->msc_front = (sii9234->msc_front + 1) % MSC_MAX_QUEUE;
1640         if (sii9234->msc_front > sii9234->msc_rear ||
1641                 (sii9234->msc_front == 0 &&
1642                         sii9234->msc_rear == MSC_MAX_QUEUE-1))
1643                 sii9234->msc_front--;
1644
1645         /* check if next work is in queue */
1646         if (!sii9234->msc_queue[sii9234->msc_front].sent) {
1647                 pr_info("%s() msc work schedule\n", __func__);
1648                 schedule_work(&sii9234->msc_work);
1649         }
1650
1651         mutex_unlock(&sii9234->msc_lock);
1652 }
1653
1654 static void sii9234_enqueue_msc_work(struct sii9234_data *sii9234, u8 command,
1655                 u8 offset, u8 data_1, u8 data_2)
1656 {
1657         int next_idx;
1658
1659         next_idx = (sii9234->msc_rear + 1) % MSC_MAX_QUEUE;
1660
1661         if (next_idx == sii9234->msc_front) {
1662                 pr_info("%s queue full\n", __func__);
1663                 return;
1664         }
1665
1666         sii9234->msc_queue[sii9234->msc_rear].command = command;
1667         sii9234->msc_queue[sii9234->msc_rear].offset = offset;
1668         sii9234->msc_queue[sii9234->msc_rear].data_1 = data_1;
1669         sii9234->msc_queue[sii9234->msc_rear].data_2 = data_2;
1670         sii9234->msc_queue[sii9234->msc_rear].sent = false;
1671
1672         sii9234->msc_rear = next_idx;
1673
1674         pr_info("%s() msc work schedule\n", __func__);
1675         schedule_work(&sii9234->msc_work);
1676 }
1677
1678 /* Must call with sii9234->lock held */
1679 static int sii9234_devcap_read_locked(struct sii9234_data *sii9234, u8 offset)
1680 {
1681         int ret;
1682         u8 val;
1683         struct msc_packet msc_pkt;
1684
1685         if (offset > 0xf)
1686                 return -EINVAL;
1687
1688         msc_pkt.command = CBUS_READ_DEVCAP;
1689         msc_pkt.offset = offset;
1690
1691         ret = sii9234_msc_req_locked(sii9234, &msc_pkt);
1692
1693         if (ret < 0)
1694                 return ret;
1695
1696         ret = cbus_read_reg(sii9234, CBUS_MSC_FIRST_DATA_IN, &val);
1697         if (ret < 0)
1698                 return ret;
1699
1700         return val;
1701 }
1702
1703
1704 void sii9234_mhl_detection_sched(void)
1705 {
1706         struct sii9234_data *sii9234 = dev_get_drvdata(sii9244_mhldev);
1707         printk(KERN_INFO "%s()\n", __func__);
1708
1709         if (!sii9234 || !sii9234->pdata) {
1710                 printk(KERN_ERR
1711                         "[ERROR] %s() getting resource is failed\n", __func__);
1712                 return;
1713         }
1714
1715         mutex_lock(&sii9234->lock);
1716         if (atomic_read(&sii9234->is_callback_scheduled) == false) {
1717                 atomic_set(&sii9234->is_callback_scheduled, true);
1718                 queue_work(sii9234_wq, &(sii9234->sii9234_int_work));
1719         } else {
1720                 pr_debug("%s(): detection callback is already scheduled.\n",
1721                                 __func__);
1722         }
1723         mutex_unlock(&sii9234->lock);
1724 }
1725 EXPORT_SYMBOL(sii9234_mhl_detection_sched);
1726
1727 static void sii9234_detection_callback(struct work_struct *p)
1728 {
1729         struct sii9234_data *sii9234;
1730         int ret;
1731         int i;
1732         u8 value;
1733
1734         printk(KERN_INFO "%s()\n", __func__);
1735
1736         sii9234 = container_of(p, struct sii9234_data, sii9234_int_work);
1737         if (sii9234 == NULL) {
1738                 printk(KERN_ERR "[ERROR] %s() sii9234 error!!\n", __func__);
1739                 return;
1740         }
1741
1742         mhl_onoff_ex(sii9234, true);
1743
1744         mutex_lock(&sii9234->lock);
1745         sii9234->link_mode = MHL_STATUS_CLK_MODE_NORMAL;
1746         sii9234->rgnd = RGND_UNKNOWN;
1747         sii9234->state = STATE_DISCONNECTED;
1748         sii9234->rsen = false;
1749         sii9234->msc_ready = false;
1750         sii9234->msc_front = 0;
1751         sii9234->msc_rear = 0;
1752
1753         /* Set the board configuration so the  SiI9234 has access to the
1754          * external connector.
1755          */
1756
1757         if (sii9234->pdata == NULL) {
1758                 printk(KERN_ERR "[ERROR] %s():%d sii9234->pdata error!!\n",
1759                        __func__, __LINE__);
1760                 goto unhandled;
1761         }
1762
1763         ret = sii9234_power_init(sii9234);
1764         if (ret < 0) {
1765                 printk(KERN_ERR "[ERROR] %s():%d sii9234_power_init failed !\n",
1766                        __func__, __LINE__);
1767                 goto unhandled;
1768         }
1769
1770         ret = sii9234_cbus_reset(sii9234);
1771         if (ret < 0) {
1772                 printk(KERN_ERR "[ERROR] %s():%d sii9234_cbus_reset failed !\n",
1773                        __func__, __LINE__);
1774                 goto unhandled;
1775         }
1776
1777         ret = sii9234_hdmi_init(sii9234);
1778         if (ret < 0) {
1779                 printk(KERN_ERR "[ERROR] %s():%d sii9234_hdmi_init failed !\n",
1780                        __func__, __LINE__);
1781                 goto unhandled;
1782         }
1783
1784         ret = sii9234_mhl_tx_ctl_int(sii9234);
1785         if (ret < 0) {
1786                 printk(KERN_ERR
1787                        "[ERROR] %s():%d sii9234_mhl_tx_ctl_init failed !\n",
1788                        __func__, __LINE__);
1789                 goto unhandled;
1790         }
1791
1792         /* Enable HDCP Compliance safety */
1793         ret = mhl_tx_write_reg(sii9234, 0x2B, 0x01);
1794         if (ret < 0) {
1795                 printk(KERN_ERR "[ERROR] %s():%d mhl_tx_write_reg failed !\n",
1796                        __func__, __LINE__);
1797                 goto unhandled;
1798         }
1799
1800         /* CBUS discovery cycle time for each drive and float = 150us */
1801         ret = mhl_tx_read_reg(sii9234, MHL_TX_DISC_CTRL1_REG, &value);
1802         if (ret < 0) {
1803                 printk(KERN_ERR "[ERROR] %s():%d mhl_tx_read_reg failed !\n",
1804                        __func__, __LINE__);
1805                 goto unhandled;
1806         }
1807
1808         value &= ~(1 << 3);
1809         value |= (1 << 2);
1810
1811         ret = mhl_tx_write_reg(sii9234, MHL_TX_DISC_CTRL1_REG, value);
1812         if (ret < 0) {
1813                 printk(KERN_ERR "[ERROR] %s():%d mhl_tx_write_reg failed !\n",
1814                        __func__, __LINE__);
1815                 goto unhandled;
1816         }
1817
1818         /* Clear bit 6 (reg_skip_rgnd) */
1819         ret = mhl_tx_write_reg(sii9234, MHL_TX_DISC_CTRL2_REG,
1820                         (1<<7) /* Reserved Bit */ |
1821                         2 << ATT_THRESH_SHIFT |
1822                         DEGLITCH_TIME_50MS);
1823         if (ret < 0) {
1824                 printk(KERN_ERR "[ERROR] %s():%d  Clear bit 6 failed !\n",
1825                        __func__, __LINE__);
1826                 goto unhandled;
1827         }
1828
1829         /* Changed from 66 to 65 for 94[1:0] = 01 = 5k reg_cbusmhl_pup_sel */
1830         /* 1.8V CBUS VTH & GND threshold */
1831         /*To meet CTS 3.3.7.2 spec*/
1832         ret = mhl_tx_write_reg(sii9234, MHL_TX_DISC_CTRL5_REG, 0x77);
1833         if (ret < 0) {
1834                 printk(KERN_ERR
1835                        "[ERROR] %s():%d write MHL_TX_DISC_CTRL5_REG failed !\n",
1836                        __func__, __LINE__);
1837                 goto unhandled;
1838         }
1839
1840         /* set bit 2 and 3, which is Initiator Timeout */
1841         ret = cbus_read_reg(sii9234, CBUS_LINK_CONTROL_2_REG, &value);
1842         if (ret < 0) {
1843                 printk(KERN_ERR
1844                        "[ERROR] %s():%d  read CBUS_LINK_CONTROL_2_REG failed !\n",
1845                        __func__, __LINE__);
1846                 goto unhandled;
1847         }
1848
1849         value |= 0x0C;
1850
1851         ret = cbus_write_reg(sii9234, CBUS_LINK_CONTROL_2_REG, value);
1852         if (ret < 0) {
1853                 printk(KERN_ERR
1854                        "[ERROR] %s():%d  write CBUS_LINK_CONTROL_2_REG failed !\n",
1855                        __func__, __LINE__);
1856                 goto unhandled;
1857         }
1858
1859         ret = mhl_tx_write_reg(sii9234, MHL_TX_MHLTX_CTL6_REG, 0xA0);
1860         if (ret < 0) {
1861                 printk(KERN_ERR
1862                        "[ERROR] %s():%d write MHL_TX_MHLTX_CTL6_REG failed !\n",
1863                        __func__, __LINE__);
1864                 goto unhandled;
1865         }
1866
1867         /* RGND & single discovery attempt (RGND blocking) */
1868         ret = mhl_tx_write_reg(sii9234, MHL_TX_DISC_CTRL6_REG, 0x71);
1869         if (ret < 0) {
1870                 printk(KERN_ERR
1871                        "[ERROR] %s():%d write MHL_TX_DISC_CTRL6_REG failed !\n",
1872                        __func__, __LINE__);
1873                 goto unhandled;
1874         }
1875
1876         /* Use VBUS path of discovery state machine */
1877         ret = mhl_tx_write_reg(sii9234, MHL_TX_DISC_CTRL8_REG, 0x0);
1878         if (ret < 0) {
1879                 printk(KERN_ERR
1880                        "[ERROR] %s():%d write MHL_TX_DISC_CTRL8_REG failed !\n",
1881                        __func__, __LINE__);
1882                 goto unhandled;
1883         }
1884
1885         /* To allow RGND engine to operate correctly.
1886          * When moving the chip from D2 to D0 (power up, init regs)
1887          * the values should be
1888          * 94[1:0] = 01  reg_cbusmhl_pup_sel[1:0] should be set for 5k
1889          * 93[7:6] = 10  reg_cbusdisc_pup_sel[1:0] should be
1890          * set for 10k (default)
1891          * 93[5:4] = 00  reg_cbusidle_pup_sel[1:0] = open (default)
1892          */
1893         /* siliconimage recommanded value is 0xA6 But make detection error */
1894 /*      ret = mhl_tx_set_reg(sii9234, MHL_TX_DISC_CTRL3_REG, 0x86); */
1895         ret = mhl_tx_set_reg(sii9234, MHL_TX_DISC_CTRL3_REG, 0xA6);
1896         if (ret < 0) {
1897                 printk(KERN_ERR
1898                        "[ERROR] %s():%d set MHL_TX_DISC_CTRL3_REG failed !\n",
1899                        __func__, __LINE__);
1900                 goto unhandled;
1901         }
1902
1903         /* change from CC to 8C to match 5K */
1904         /*To meet CTS 3.3.72 spec*/
1905         ret = mhl_tx_set_reg(sii9234, MHL_TX_DISC_CTRL4_REG, 0x8C);
1906         if (ret < 0) {
1907                 printk(KERN_ERR
1908                        "[ERROR] %s():%d set MHL_TX_DISC_CTRL4_REG failed !\n",
1909                        __func__, __LINE__);
1910                 goto unhandled;
1911         }
1912
1913         /* Force upstream HPD to 0 when not in MHL mode */
1914         mhl_tx_clear_reg(sii9234, MHL_TX_INT_CTRL_REG, MHL_HPD_OUT_OVR_VAL);
1915         mhl_tx_set_reg(sii9234, MHL_TX_INT_CTRL_REG, MHL_HPD_OUT_OVR_EN);
1916
1917         /* Configure the interrupt as active high */
1918         ret =
1919             mhl_tx_clear_reg(sii9234, MHL_TX_INT_CTRL_REG, (1 << 2) | (1 << 1));
1920         if (ret < 0) {
1921                 printk(KERN_ERR
1922                        "[ERROR] %s():%d clear MHL_TX_INT_CTRL_REG failed !\n",
1923                        __func__, __LINE__);
1924                 goto unhandled;
1925         }
1926
1927         msleep(25);
1928
1929         ret = mhl_tx_write_reg(sii9234, MHL_TX_DISC_CTRL1_REG, 0x27);
1930         if (ret < 0) {
1931                 printk(KERN_ERR
1932                        "[ERROR] %s():%dwrite MHL_TX_DISC_CTRL1_REG failed !\n",
1933                        __func__, __LINE__);
1934                 goto unhandled;
1935         }
1936
1937         sii9234_cbus_init(sii9234);
1938
1939         /* Enable Auto soft reset on SCDT = 0 */
1940         ret = mhl_tx_write_reg(sii9234, 0x05, 0x04);
1941         if (ret < 0) {
1942                 printk(KERN_ERR "[ERROR] %s():%d write 0x05 failed !\n",
1943                        __func__, __LINE__);
1944                 goto unhandled;
1945         }
1946
1947         /* HDMI Transcode mode enable */
1948         ret = mhl_tx_write_reg(sii9234, 0x0D, 0x1C);
1949         if (ret < 0) {
1950                 printk(KERN_ERR
1951                        "[ERROR] %s():%dHDMI Transcode mode enable failed !\n",
1952                        __func__, __LINE__);
1953                 goto unhandled;
1954         }
1955
1956         ret = mhl_tx_write_reg(sii9234, MHL_TX_INTR4_ENABLE_REG,
1957                                RGND_READY_MASK | CBUS_LKOUT_MASK |
1958                                MHL_DISC_FAIL_MASK | MHL_EST_MASK);
1959         if (ret < 0) {
1960                 printk(KERN_ERR
1961                        "[ERROR] %s():%d write MHL_TX_INTR4_ENABLE_REG failed !\n",
1962                        __func__, __LINE__);
1963                 goto unhandled;
1964         }
1965
1966         ret = mhl_tx_write_reg(sii9234, MHL_TX_INTR1_ENABLE_REG,
1967                                                 RSEN_CHANGE_INT_MASK);
1968         if (ret < 0) {
1969                 printk(KERN_ERR
1970                        "[ERROR] %s():%dwrite MHL_TX_INTR1_ENABLE_REG failed !\n",
1971                        __func__, __LINE__);
1972                 goto unhandled;
1973         }
1974
1975         ret = cbus_write_reg(sii9234, CBUS_INT_1_MASK,
1976                                         CBUS_INTR_STATUS_1_ENABLE_MASK);
1977         if (ret < 0) {
1978                 printk(KERN_ERR
1979                        "[ERROR] %s() cbus register init failed !\n",
1980                        __func__);
1981                 goto unhandled;
1982         }
1983
1984         ret = cbus_write_reg(sii9234, CBUS_INT_2_MASK,
1985                                         CBUS_INTR_STATUS_2_ENABLE_MASK);
1986         if (ret < 0)
1987                 goto unhandled;
1988
1989 /* this point is very importand before megsure RGND impedance*/
1990         force_usb_id_switch_open(sii9234);
1991
1992         mhl_tx_clear_reg(sii9234, MHL_TX_DISC_CTRL4_REG,
1993                                         (1<<7) | (1<<6) | (1<<5) | (1<<4));
1994
1995         release_usb_id_switch_open(sii9234);
1996
1997         //printk("[%d] %s\n", __LINE__, __func__);
1998         //goto unhandled;
1999
2000         pr_debug("%s(): waiting for RGND measurement\n", __func__);
2001         enable_irq(sii9234->pdata->mhl_tx_client->irq);
2002
2003         /* SiI9244 Programmer's Reference Section 2.4.3
2004          * State : RGND Ready
2005          */
2006         mutex_unlock(&sii9234->lock);
2007         ret = wait_event_timeout(sii9234->wq,
2008                                  ((sii9234->rgnd != RGND_UNKNOWN) ||
2009                                   mhl_state_is_error(sii9234->state)),
2010                                  msecs_to_jiffies(T_WAIT_TIMEOUT_RGND_INT));
2011
2012         mutex_lock(&sii9234->lock);
2013         if (ret == 0 || mhl_state_is_error(sii9234->state)) {
2014                 printk(KERN_INFO "%s():%d wait RGND Ready failed !\n",
2015                        __func__, __LINE__);
2016                 goto unhandled;
2017         }
2018
2019         if (sii9234->rgnd != RGND_1K) {
2020                 printk(KERN_ERR "[ERROR] %s():%d rgnd impedance failed !\n",
2021                        __func__, __LINE__);
2022                 goto unhandled;
2023         }
2024
2025         mutex_unlock(&sii9234->lock);
2026
2027         pr_debug("%s(): waiting for detection\n", __func__);
2028         ret = wait_event_timeout(sii9234->wq,
2029                                  sii9234->state != STATE_DISCONNECTED,
2030                                  msecs_to_jiffies(T_WAIT_TIMEOUT_DISC_INT));
2031
2032         mutex_lock(&sii9234->lock);
2033         if (ret == 0) {
2034                 printk(KERN_ERR
2035                        "[ERROR] %s():%d wait detection state failed !\n",
2036                        __func__, __LINE__);
2037                 goto unhandled;
2038         }
2039
2040         if (sii9234->state == STATE_DISCONNECTED) {
2041                 printk(KERN_ERR
2042                        "[ERROR] %s():%d sii9234->state is STATE_DISCONNECTED !\n",
2043                        __func__, __LINE__);
2044                 goto unhandled;
2045         }
2046
2047         if (sii9234->state == STATE_DISCOVERY_FAILED) {
2048                 printk(KERN_ERR
2049                        "[ERROR] %s():%d STATE_DISCOVERY_FAILED failed !\n",
2050                        __func__, __LINE__);
2051                 goto unhandled;
2052         }
2053
2054         if (mhl_state_is_error(sii9234->state)) {
2055                 printk(KERN_ERR "[ERROR] %s():%d mhl_state_is_error failed !\n",
2056                        __func__, __LINE__);
2057                 goto unhandled;
2058         }
2059
2060         mutex_unlock(&sii9234->lock);
2061         pr_debug("%s(): waiting for RSEN_INT\n", __func__);
2062         ret = wait_event_timeout(sii9234->wq, sii9234->rsen,
2063                                  msecs_to_jiffies(T_WAIT_TIMEOUT_RSEN_INT));
2064         mutex_lock(&sii9234->lock);
2065
2066         if (!sii9234->rsen) {
2067                 ret = mhl_tx_read_reg(sii9234, MHL_TX_SYSSTAT_REG, &value);
2068                 pr_debug("%s(): Recheck RSEN value\n", __func__);
2069                 if (!(ret && (value & RSEN_STATUS))) {
2070                         usleep_range(T_SRC_RXSENSE_DEGLITCH * USEC_PER_MSEC,
2071                                         T_SRC_RXSENSE_DEGLITCH * USEC_PER_MSEC);
2072                         pr_debug("%s(): RSEN is low -> retry once\n", __func__);
2073
2074                         ret = mhl_tx_read_reg(sii9234, MHL_TX_SYSSTAT_REG,
2075                                                                 &value);
2076                         if (!(ret && (value & RSEN_STATUS))) {
2077                                 pr_debug("%s(): RSEN is still low\n", __func__);
2078                                 goto unhandled;
2079                         }
2080
2081                 }
2082                 sii9234->rsen = value & RSEN_STATUS;
2083         }
2084         pr_info("%s(): RSEN OK\n", __func__);
2085
2086 #ifdef  CONFIG_SAMSUNG_WORKAROUND_HPD_GLANCE
2087         mhl_hpd_handler(true);
2088 #endif
2089
2090         mutex_unlock(&sii9234->lock);
2091
2092         ret = wait_event_timeout(sii9234->wq, sii9234->msc_ready,
2093                                                 msecs_to_jiffies(2000));
2094
2095         if (sii9234->msc_ready) {
2096                 pr_info("%s(): read devcap\n", __func__);
2097                 memset(sii9234->devcap, 0x0, sizeof(sii9234->devcap));
2098                 for (i = 0; i < 16; i++) {
2099                         mutex_lock(&sii9234->msc_lock);
2100                         mutex_lock(&sii9234->lock);
2101                         ret = sii9234_devcap_read_locked(sii9234, i);
2102                         mutex_unlock(&sii9234->lock);
2103                         if (ret < 0) {
2104                                 mutex_unlock(&sii9234->msc_lock);
2105                                 break;
2106                         }
2107                         sii9234->devcap[i] = ret;
2108                         mutex_unlock(&sii9234->msc_lock);
2109                 }
2110 #ifdef DEBUG
2111                 if (ret >= 0)
2112                         print_hex_dump(KERN_DEBUG, "sii9234: devcap = ",
2113                                                 DUMP_PREFIX_NONE, 16, 1,
2114                                                 sii9234->devcap, 16, false);
2115 #endif
2116         } else {
2117                 printk(KERN_ERR"%s() msc not ready : ret=%d, msc_ready=%d\n",
2118                         __func__, ret, sii9234->msc_ready);
2119         }
2120         mutex_lock(&sii9234->lock);
2121
2122         /* It's possible for devcap reading to fail but the adapter still
2123          * be connected.  Therefore we must keep ownership of the port
2124          * as long as it's still connected.
2125          */
2126         if (sii9234->state != STATE_ESTABLISHED) {
2127                 printk(KERN_ERR"%s() state is wrong : 0x%x\n",
2128                         __func__, sii9234->state);
2129                 goto unhandled;
2130         }
2131
2132         pr_info("%s(): connection established\n", __func__);
2133
2134         sii9234->claimed = true;
2135         mutex_unlock(&sii9234->lock);
2136
2137         return;
2138
2139  unhandled:
2140         pr_info("%s(): Detection failed", __func__);
2141         if (sii9234->state == STATE_DISCONNECTED)
2142                 pr_cont(" (timeout)");
2143         else if (sii9234->state == STATE_DISCOVERY_FAILED)
2144                 pr_cont(" (discovery failed)");
2145         else if (sii9234->state == STATE_CBUS_LOCKOUT)
2146                 pr_cont(" (cbus_lockout)");
2147         pr_cont("\n");
2148
2149         pr_info("%s() mhl power off\n", __func__);
2150         mutex_unlock(&sii9234->lock);
2151         mhl_onoff_ex(sii9234, false);
2152
2153         pr_debug("%s(): dectection callback finished\n", __func__);
2154         return;
2155 }
2156
2157 #ifdef  CONFIG_SII9234_CBUS
2158
2159 static int sii9234_cbus_irq(struct sii9234_data *sii9234)
2160 {
2161         u8 cbus_intr1, cbus_intr2;
2162         u8 mhl_intr0, mhl_intr1;
2163         u8 mhl_status0, mhl_status1, mhl_status2, mhl_status3;
2164
2165         int ret = 0;
2166
2167         cbus_read_reg(sii9234, CBUS_INT_STATUS_1_REG, &cbus_intr1);
2168         cbus_read_reg(sii9234, CBUS_INT_STATUS_2_REG, &cbus_intr2);
2169         cbus_read_reg(sii9234, CBUS_MHL_INTR_REG_0, &mhl_intr0);
2170         cbus_read_reg(sii9234, CBUS_MHL_INTR_REG_1, &mhl_intr1);
2171         cbus_read_reg(sii9234, CBUS_MHL_STATUS_REG_0, &mhl_status0);
2172         cbus_read_reg(sii9234, CBUS_MHL_STATUS_REG_1, &mhl_status1);
2173         cbus_read_reg(sii9234, CBUS_MHL_STATUS_REG_2, &mhl_status2);
2174         cbus_read_reg(sii9234, CBUS_MHL_STATUS_REG_3, &mhl_status3);
2175
2176         pr_debug("%s(): intr %02x %02x\n", __func__, cbus_intr1, cbus_intr2);
2177
2178         if (cbus_intr1 & MSC_RESP_ABORT)
2179                 cbus_resp_abort_error(sii9234);
2180
2181         if (cbus_intr1 & MSC_REQ_ABORT)
2182                 cbus_req_abort_error(sii9234);
2183
2184         if (cbus_intr1 & CBUS_DDC_ABORT) {
2185                 pr_debug("%s(): CBUS DDC abort\n", __func__);
2186                 if (cbus_ddc_abort_error(sii9234)) {
2187                         printk(KERN_ERR "%s() ddc abort error\n", __func__);
2188                         goto err_handler;
2189                 }
2190         }
2191
2192         if (cbus_intr1 & MSC_REQ_DONE) {
2193                 pr_debug("%s(): msc request done\n", __func__);
2194                 complete(&sii9234->msc_complete);
2195         }
2196
2197         if (cbus_intr1 & MSC_MSG_RECD) {
2198                 pr_debug("%s(): msc msg received\n", __func__);
2199                 cbus_handle_msc_msg(sii9234);
2200         }
2201
2202         if (cbus_intr2 & WRT_STAT_RECD) {
2203                 pr_debug("%s(): write stat received\n", __func__);
2204                 cbus_handle_wrt_stat_recd(sii9234);
2205                 sii9234->msc_ready = mhl_status0 & MHL_STATUS_DCAP_READY;
2206         }
2207
2208         if (cbus_intr2 & SET_INT_RECD)
2209                 cbus_handle_set_int_recd(sii9234);
2210
2211         if (cbus_intr2 & WRT_BURST_RECD)
2212                 pr_debug("%s(): write burst received\n", __func__);
2213
2214         cbus_write_reg(sii9234, CBUS_INT_STATUS_1_REG, cbus_intr1);
2215         cbus_write_reg(sii9234, CBUS_INT_STATUS_2_REG, cbus_intr2);
2216         cbus_write_reg(sii9234, CBUS_MHL_INTR_REG_0, mhl_intr0);
2217         cbus_write_reg(sii9234, CBUS_MHL_INTR_REG_1, mhl_intr1);
2218         cbus_write_reg(sii9234, CBUS_MHL_STATUS_REG_0, 0xFF);
2219         cbus_write_reg(sii9234, CBUS_MHL_STATUS_REG_1, 0xFF);
2220         cbus_write_reg(sii9234, CBUS_MHL_STATUS_REG_2, 0xFF);
2221         cbus_write_reg(sii9234, CBUS_MHL_STATUS_REG_3, 0xFF);
2222
2223         return ret;
2224
2225 err_handler:
2226         mhl_onoff_ex(sii9234, false);
2227
2228         return  -1;
2229 }
2230
2231 #endif /* CONFIG_SII9234_CBUS */
2232
2233 static u8 sii9234_tmds_control(struct sii9234_data *sii9234, bool enable)
2234 {
2235
2236         u8 ret = -1;
2237
2238         if (enable) {
2239                 ret = mhl_tx_set_reg(sii9234, MHL_TX_TMDS_CCTRL, (1<<4));
2240                 if (ret < 0) {
2241                         printk(KERN_ERR "%s() mhl_tx_set_reg fail\n", __func__);
2242                         return ret;
2243                 }
2244                 pr_debug("%s() MHL HPD High, enabled TMDS\n",
2245                         __func__);
2246                 ret = mhl_tx_set_reg(sii9234, MHL_TX_INT_CTRL_REG,
2247                         MHL_HPD_OUT_OVR_EN | MHL_HPD_OUT_OVR_VAL);
2248                 if (ret < 0) {
2249                         printk(KERN_ERR
2250                                 "%s() mhl_tx_set_reg fail\n", __func__);
2251                         return ret;
2252                 }
2253         } else {
2254                 ret = mhl_tx_clear_reg(sii9234, MHL_TX_TMDS_CCTRL, (1<<4));
2255                 if (ret < 0) {
2256                         printk(KERN_ERR
2257                                 "%s() mhl_tx_clear_reg fail\n", __func__);
2258                         return ret;
2259                 }
2260                 pr_debug("%s() MHL HPD low, disabled TMDS\n", __func__);
2261
2262                 /* HPD force low - fixed issue unbalanced hpd state */
2263                 ret = mhl_tx_clear_reg(sii9234, MHL_TX_INT_CTRL_REG,
2264                                                         MHL_HPD_OUT_OVR_VAL);
2265                 if (ret < 0) {
2266                         printk(KERN_ERR
2267                                 "%s() clear MHL_TX_INT_CTRL_REG fail\n",
2268                                 __func__);
2269                         return ret;
2270                 }
2271                 ret = mhl_tx_set_reg(sii9234, MHL_TX_INT_CTRL_REG,
2272                                                         MHL_HPD_OUT_OVR_EN);
2273                 if (ret < 0) {
2274                         printk(KERN_ERR
2275                                 "%s() set MHL_TX_INT_CTRL_REG fail\n",
2276                                 __func__);
2277                         return ret;
2278                 }
2279                 pr_info("%s(): MHL HPD low, disabled TMDS\n", __func__);
2280         }
2281
2282         return ret;
2283 }
2284
2285 static irqreturn_t sii9234_irq_thread(int irq, void *data)
2286 {
2287         struct sii9234_data *sii9234 = data;
2288         int ret;
2289         u8 intr1, intr4, value;
2290         u8 intr1_en, intr4_en;
2291         u8 mhl_poweroff = 0;
2292
2293
2294         mutex_lock(&sii9234->lock);
2295         ret = mhl_tx_read_reg(sii9234, MHL_TX_INTR1_REG, &intr1);
2296         if (ret < 0) {
2297                 printk(KERN_ERR
2298                        "[ERROR] %s():%d read MHL_TX_INTR1_REG failed !\n",
2299                        __func__, __LINE__);
2300                 goto i2c_error_exit;
2301         }
2302
2303         ret = mhl_tx_read_reg(sii9234, MHL_TX_INTR4_REG, &intr4);
2304         if (ret < 0) {
2305                 printk(KERN_ERR
2306                        "[ERROR] %s():%d read MHL_TX_INTR4_REG failed !\n",
2307                        __func__, __LINE__);
2308                 goto i2c_error_exit;
2309         }
2310
2311         ret = mhl_tx_read_reg(sii9234, MHL_TX_INTR1_ENABLE_REG, &intr1_en);
2312         if (ret < 0) {
2313                 printk(KERN_ERR
2314                        "[ERROR] %s():%d read MHL_TX_INTR1_ENABLE_REG failed !\n",
2315                        __func__, __LINE__);
2316                 goto i2c_error_exit;
2317         }
2318
2319         ret = mhl_tx_read_reg(sii9234, MHL_TX_INTR4_ENABLE_REG, &intr4_en);
2320         if (ret < 0) {
2321                 printk(KERN_ERR
2322                        "[ERROR] %s():%d read MHL_TX_INTR4_ENABLE_REG failed !\n",
2323                        __func__, __LINE__);
2324                 goto i2c_error_exit;
2325         }
2326
2327         pr_debug("%s(): irq %02x/%02x %02x/%02x\n", __func__, intr1, intr1_en,
2328                  intr4, intr4_en);
2329
2330         if (intr4 & RGND_READY_INT) {
2331                 ret = mhl_tx_read_reg(sii9234, MHL_TX_STAT2_REG, &value);
2332                 if (ret < 0) {
2333                         dev_err(&sii9234->pdata->mhl_tx_client->dev,
2334                                         "STAT2 reg, err %d\n", ret);
2335                         goto err_exit;
2336                 }
2337
2338                 switch (value & RGND_INTP_MASK) {
2339                 case RGND_INTP_OPEN:
2340                         pr_debug("%s(): RGND Open\n", __func__);
2341                         sii9234->rgnd = RGND_OPEN;
2342                         break;
2343                 case RGND_INTP_1K:
2344                         pr_debug("%s(): RGND 1K\n", __func__);
2345                         ret = mhl_tx_set_reg(sii9234, MHL_TX_DISC_CTRL4_REG,
2346                                 0x8C);
2347                         if (ret < 0) {
2348                                 printk(KERN_ERR
2349                                        "[ERROR] %s():%d write MHL_TX_DISC_CTRL4_REG failed !\n",
2350                                        __func__, __LINE__);
2351                                 goto i2c_error_exit;
2352                         }
2353
2354                         ret = mhl_tx_set_reg(sii9234,
2355                                 MHL_TX_DISC_CTRL6_REG, 0x05);
2356                         if (ret < 0) {
2357                                 printk(KERN_ERR
2358                                        "[ERROR] %s():%d write MHL_TX_DISC_CTRL6_REG failed !\n",
2359                                        __func__, __LINE__);
2360                                 goto i2c_error_exit;
2361                         }
2362
2363                         usleep_range(T_SRC_VBUS_CBUS_TO_STABLE * USEC_PER_MSEC,
2364                                 T_SRC_VBUS_CBUS_TO_STABLE  * USEC_PER_MSEC);
2365
2366                         ret = mhl_send_wake_pulses(sii9234);
2367                         if (ret < 0) {
2368                                 printk(KERN_ERR
2369                                        "[ERROR] %s():%d mhl_send_wake_pulses failed !\n",
2370                                        __func__, __LINE__);
2371                                 goto i2c_error_exit;
2372                         }
2373                         sii9234->rgnd = RGND_1K;
2374
2375                         cbus_write_reg(sii9234, CBUS_INT_1_MASK, 0);
2376                         cbus_write_reg(sii9234, CBUS_INT_2_MASK, 0);
2377                         break;
2378                 case RGND_INTP_2K:
2379                         pr_debug("%s(): RGND 2K\n", __func__);
2380                         sii9234->rgnd = RGND_2K;
2381                         break;
2382                 case RGND_INTP_SHORT:
2383                         pr_debug("%s(): RGND Short\n", __func__);
2384                         sii9234->rgnd = RGND_SHORT;
2385                         break;
2386                 }
2387         }
2388
2389         if (intr4 & CBUS_LKOUT_INT) {
2390                 pr_debug("%s(): CBUS Lockout Interrupt\n", __func__);
2391                 sii9234->state = STATE_CBUS_LOCKOUT;
2392         }
2393
2394         if (intr4 & MHL_DISC_FAIL_INT) {
2395                 printk(KERN_ERR "[ERROR] %s(): MHL_DISC_FAIL_INT\n", __func__);
2396                 sii9234->state = STATE_DISCOVERY_FAILED;
2397         }
2398
2399         if (intr4 & MHL_EST_INT) {
2400                 pr_debug("%s(): mhl est interrupt %d\n", __func__, value);
2401
2402                 /* discovery override */
2403                 ret = mhl_tx_write_reg(sii9234, MHL_TX_MHLTX_CTL1_REG, 0x10);
2404                 if (ret < 0) {
2405                         printk(KERN_ERR
2406                                "[ERROR] %s():%d write MHL_TX_MHLTX_CTRL1_REG failed !\n",
2407                                __func__, __LINE__);
2408                         goto i2c_error_exit;
2409                 }
2410
2411                 /* increase DDC translation layer timer (byte mode) */
2412                 ret = cbus_write_reg(sii9234, 0x07, 0x32);
2413                 if (ret < 0) {
2414                         printk(KERN_ERR
2415                                "[ERROR] %s():%d cbus_write_reg failed !\n",
2416                                __func__, __LINE__);
2417                         goto i2c_error_exit;
2418                 }
2419                 ret = cbus_set_reg(sii9234, 0x44, 1 << 1);
2420                 if (ret < 0) {
2421                         printk(KERN_ERR
2422                                "[ERROR] %s():%d cbus_set_reg failed !\n",
2423                                __func__, __LINE__);
2424                         goto i2c_error_exit;
2425                 }
2426
2427                 /* Keep the discovery enabled. Need RGND interrupt */
2428                 ret = mhl_tx_set_reg(sii9234, MHL_TX_DISC_CTRL1_REG, (1 << 0));
2429                 if (ret < 0) {
2430                         printk(KERN_ERR
2431                                "[ERROR] %s():%d mhl_tx_set_reg failed !\n",
2432                                __func__, __LINE__);
2433                         goto i2c_error_exit;
2434                 }
2435
2436                 sii9234->state = STATE_ESTABLISHED;
2437 #ifdef  CONFIG_SII9234_CBUS
2438                 sii9234_enqueue_msc_work(sii9234, CBUS_SET_INT, MHL_RCHANGE_INT,
2439                                                 MHL_INT_DCAP_CHG, 0x0);
2440
2441                 mhl_tx_write_reg(sii9234, MHL_TX_INTR1_ENABLE_REG,
2442                                 RSEN_CHANGE_INT_MASK | HPD_CHANGE_INT_MASK);
2443
2444                 cbus_write_reg(sii9234, CBUS_INT_1_MASK,
2445                                         CBUS_INTR_STATUS_1_ENABLE_MASK);
2446                 cbus_write_reg(sii9234, CBUS_INT_2_MASK,
2447                                         CBUS_INTR_STATUS_2_ENABLE_MASK);
2448 #endif
2449         }
2450
2451         if (intr1 & HPD_CHANGE_INT) {
2452                 ret = cbus_read_reg(sii9234, MSC_REQ_ABORT_REASON_REG, &value);
2453
2454                 if (value & SET_HPD_DOWNSTREAM) {
2455                         pr_info("%s() hpd high\n", __func__);
2456
2457 #ifdef CONFIG_SII9234_CBUS
2458                         sii9234_enqueue_msc_work(sii9234, CBUS_WRITE_STAT,
2459                                                 CBUS_LINK_CONTROL_2_REG,
2460                                                 sii9234->link_mode, 0x0);
2461 #endif
2462                         /* Enable TMDS */
2463                         ret = sii9234_tmds_control(sii9234, true);
2464                         if (ret < 0) {
2465                                 printk(KERN_ERR
2466                                        "[ERROR] %s():%d set sii9234_tmds_control\n",
2467                                        __func__, __LINE__);
2468                                 goto i2c_error_exit;
2469                         }
2470                         pr_debug("%s(): MHL HPD High, enabled TMDS\n",
2471                                 __func__);
2472
2473                 } else {
2474                         pr_info("%s(): hpd low\n", __func__);
2475                         /* Disable TMDS */
2476                         ret = sii9234_tmds_control(sii9234, false);
2477                         if (ret < 0) {
2478                                 printk(KERN_ERR
2479                                        "[ERROR] %s():%d set sii9234_tmds_control\n",
2480                                        __func__, __LINE__);
2481                                 goto i2c_error_exit;
2482                         }
2483                 }
2484         }
2485
2486         if (intr1 & RSEN_CHANGE_INT) {
2487                 ret = mhl_tx_read_reg(sii9234, MHL_TX_SYSSTAT_REG, &value);
2488
2489                 sii9234->rsen = value & RSEN_STATUS;
2490
2491                 if (value & RSEN_STATUS) {
2492                         pr_info("%s(): MHL cable connected.. RSEN High\n",
2493                                 __func__);
2494                 } else {
2495                         pr_info("%s(): RSEN lost\n", __func__);
2496                         /* Once RSEN loss is confirmed,we need to check
2497                          * based on cable status and chip power status,whether
2498                          * it is SINK Loss(HDMI cable not connected, TV Off)
2499                          * or MHL cable disconnection
2500                          */
2501                         usleep_range(T_SRC_RXSENSE_DEGLITCH * USEC_PER_MSEC,
2502                                         T_SRC_RXSENSE_DEGLITCH * USEC_PER_MSEC);
2503                         ret = mhl_tx_read_reg(sii9234, MHL_TX_SYSSTAT_REG,
2504                                                                  &value);
2505                         if (ret < 0) {
2506                                 printk(KERN_ERR
2507                                         "[ERROR] %s() read MHL_TX_SYSSTAT_REG\n",
2508                                         __func__);
2509                                 goto err_exit;
2510                         }
2511                         pr_info("%s(): sys_stat: %x ~\n", __func__, value);
2512
2513                 if ((value & RSEN_STATUS) == 0) {
2514                         printk(KERN_INFO
2515                                 "%s() RSEN Really LOW ~\n", __func__);
2516
2517                         sii9234_tmds_control(sii9234, false);
2518                         mhl_poweroff = true;
2519                         goto i2c_error_exit;
2520                         }
2521                 }
2522         }
2523
2524 #ifdef  CONFIG_SII9234_CBUS
2525         if (sii9234->state == STATE_ESTABLISHED)
2526                 sii9234_cbus_irq(sii9234);
2527 #endif
2528
2529 err_exit:
2530         mhl_tx_write_reg(sii9234, MHL_TX_INTR1_REG, intr1);
2531         mhl_tx_write_reg(sii9234, MHL_TX_INTR4_REG, intr4);
2532
2533         mutex_unlock(&sii9234->lock);
2534
2535         pr_debug("%s(): wake_up\n", __func__);
2536         wake_up(&sii9234->wq);
2537
2538         return IRQ_HANDLED;
2539
2540 i2c_error_exit:
2541         mutex_unlock(&sii9234->lock);
2542
2543         pr_info("%s(): wake_up\n", __func__);
2544         wake_up(&sii9234->wq);
2545
2546         if (mhl_poweroff) {
2547                 printk(KERN_INFO "%s() mhl_poweroff\n", __func__);
2548                 mhl_onoff_ex(sii9234, false);
2549         }
2550
2551         return IRQ_HANDLED;
2552 }
2553
2554 #ifdef CONFIG_SS_FACTORY
2555 #define SII_ID 0x92
2556 static ssize_t sysfs_check_mhl_command(struct class *class,
2557         struct class_attribute *attr, char *buf)
2558 {
2559         int size;
2560         u8 sii_id = 0;
2561         struct sii9234_data *sii9234 = dev_get_drvdata(sii9244_mhldev);
2562
2563         if (sii9234->pdata->hw_onoff)
2564                 sii9234->pdata->hw_onoff(1);
2565
2566         if (sii9234->pdata->hw_reset)
2567                 sii9234->pdata->hw_reset();
2568
2569         mhl_tx_read_reg(sii9234, MHL_TX_IDH_REG, &sii_id);
2570         pr_info("sii9234: %s() sel_show sii_id: %X\n", __func__, sii_id);
2571
2572         if (sii9234->pdata->hw_onoff)
2573                 sii9234->pdata->hw_onoff(1);
2574
2575         size = snprintf(buf, 10, "%d\n", sii_id == SII_ID ? 1 : 0);
2576
2577         return size;
2578
2579 }
2580
2581 static CLASS_ATTR(test_result, 0664 , sysfs_check_mhl_command, NULL);
2582 #endif /*config_ss_factory*/
2583
2584 static ssize_t sysfs_sii9234_ddc_i2c_num_show(struct class *class,
2585         struct class_attribute *attr, char *buf)
2586 {
2587         int size;
2588         struct sii9234_data *sii9234 = dev_get_drvdata(sii9244_mhldev);
2589
2590         pr_info("%s() ddc_i2c_num : %d\n",
2591                 __func__, sii9234->pdata->ddc_i2c_num);
2592         size = sprintf(buf, "DDC %d\n", sii9234->pdata->ddc_i2c_num);
2593
2594         return size;
2595 }
2596
2597 static CLASS_ATTR(ddc_i2c_num, 0664 , sysfs_sii9234_ddc_i2c_num_show, NULL);
2598
2599 static ssize_t sysfs_mhl_read_reg_show(struct device *dev,
2600                                  struct device_attribute *attr, char *buf)
2601 {
2602         pr_info("sii9234: %s()\n", __func__);
2603         return sprintf(buf, "sysfs_mhl_read_reg_show\n");
2604 }
2605
2606 #if 0
2607 static ssize_t sysfs_mhl_read_reg_store(struct device *dev,
2608                                   struct device_attribute *attr,
2609                                   const char *buf, size_t size)
2610 {
2611         struct sii9234_data *sii9234 = dev_get_drvdata(sii9244_mhldev);
2612         enum page_num pn;
2613         unsigned int offset;
2614         int ret;
2615         u8 value = 0;
2616         char dest[10];
2617         char *buffer = (char *)buf;
2618
2619         if (size > 10) {
2620                 pr_info("sii9234: Error : Unsupported format\n");
2621                 return size;
2622         }
2623
2624         if (strnicmp(buf, "mhl", 3) == 0) {
2625                 printk(KERN_INFO "sii9234: %s() - mhl start\n", __func__);
2626                 sii9234_mhl_detection_sched();
2627         }
2628
2629         strcpy(dest, strsep(&buffer, ":"));
2630         ret = kstrtouint(dest, 0, &offset);
2631         if (ret != 0) {
2632                 pr_info("sii9234: Error : Page number\n");
2633                 return size;
2634         }
2635         pn = (enum page_num)offset;
2636
2637         strcpy(dest, buffer);
2638         ret = kstrtouint(dest, 0, &offset);
2639         if (ret || offset > 0xff) {
2640                 pr_info("sii9234: Error : Offset number\n");
2641                 return size;
2642         }
2643
2644         switch (pn) {
2645         case PAGE0:
2646                 mhl_tx_read_reg(sii9234, offset, &value);
2647                 break;
2648         case PAGE1:
2649                 tpi_read_reg(sii9234, offset, &value);
2650                 break;
2651         case PAGE2:
2652                 hdmi_rx_read_reg(sii9234, offset, &value);
2653                 break;
2654         case PAGE3:
2655                 cbus_read_reg(sii9234, offset, &value);
2656                 break;
2657         default:
2658                 pr_info("\nsii9234: Error : Out of the page number range\n");
2659                 return size;
2660         }
2661         pr_info("sii9234: MHL register Page%d:0x%02x = 0x%02x\n", pn, offset,
2662                 value);
2663
2664         return size;
2665 }
2666
2667 static DEVICE_ATTR(mhl_read_reg, S_IRUGO | S_IWUSR,
2668                    sysfs_mhl_read_reg_show, sysfs_mhl_read_reg_store);
2669 #endif
2670 static DEVICE_ATTR(mhl_read_reg, S_IRUGO, sysfs_mhl_read_reg_show, NULL);
2671
2672 #ifdef CONFIG_MHL_DEBUG
2673 module_param_named(mhl_dbg_flag, mhl_dbg_flag, uint, 0644);
2674 #endif
2675
2676 #ifdef CONFIG_MACH_MIDAS
2677 void sii9234_wake_lock(void)
2678 {
2679         struct sii9234_data *sii9234 = dev_get_drvdata(sii9244_mhldev);
2680         wake_lock(&sii9234->wlock);
2681         pr_debug("%s()\n", __func__);
2682 }
2683 EXPORT_SYMBOL(sii9234_wake_lock);
2684
2685 void sii9234_wake_unlock(void)
2686 {
2687         struct sii9234_data *sii9234 = dev_get_drvdata(sii9244_mhldev);
2688         wake_unlock(&sii9234->wlock);
2689         pr_debug("%s()\n", __func__);
2690 }
2691 EXPORT_SYMBOL(sii9234_wake_unlock);
2692 #endif
2693
2694 static int __devinit sii9234_mhl_tx_i2c_probe(struct i2c_client *client,
2695                                               const struct i2c_device_id *id)
2696 {
2697         struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
2698         struct sii9234_data *sii9234;
2699 #ifdef CONFIG_SII9234_RCP
2700         struct input_dev *input;
2701 #endif
2702         int ret;
2703 #ifdef CONFIG_SS_FACTORY
2704         struct class *sec_mhl;
2705 #endif
2706
2707 #ifdef CONFIG_MHL_DEBUG
2708         mhl_dbg_flag = 1;
2709 #endif
2710
2711         printk(KERN_INFO "%s()\n", __func__);
2712
2713         if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
2714                 printk(KERN_ERR "[ERROR] %s() i2c no function\n", __func__);
2715                 return -EIO;
2716         }
2717
2718         sii9234 = kzalloc(sizeof(struct sii9234_data), GFP_KERNEL);
2719         if (!sii9234) {
2720                 dev_err(&client->dev, "failed to allocate driver data\n");
2721                 return -ENOMEM;
2722         }
2723
2724         atomic_set(&sii9234->is_callback_scheduled, false);
2725 #ifdef CONFIG_SII9234_RCP
2726         input = input_allocate_device();
2727         if (!input) {
2728                 dev_err(&client->dev, "failed to allocate input device.\n");
2729                 ret = -ENOMEM;
2730                 goto err_exit0;
2731         }
2732 #endif
2733
2734         sii9234->pdata = client->dev.platform_data;
2735         if (!sii9234->pdata) {
2736                 ret = -EINVAL;
2737                 printk(KERN_ERR "[ERROR] %s() platform_data is NULL\n",
2738                        __func__);
2739                 goto err_exit1;
2740         }
2741         sii9234->pdata->mhl_tx_client = client;
2742
2743         init_waitqueue_head(&sii9234->wq);
2744         mutex_init(&sii9234->lock);
2745         mutex_init(&sii9234->msc_lock);
2746
2747         i2c_set_clientdata(client, sii9234);
2748         sii9244_mhldev = &client->dev;
2749
2750         sii9234->pdata->init();
2751
2752         ret = device_create_file(&(client->dev), &dev_attr_mhl_read_reg);
2753         if (ret < 0)
2754                 dev_err(&(client->dev), "failed to add sysfs entries\n");
2755
2756         sii9234_wq = create_singlethread_workqueue("sii9234_wq");
2757         if (!sii9234_wq) {
2758                 printk(KERN_ERR
2759                        "[ERROR] %s() workqueue create fail\n", __func__);
2760                 ret = -ENOMEM;
2761                 goto err_exit1b;
2762         }
2763         INIT_WORK(&(sii9234->sii9234_int_work), sii9234_detection_callback);
2764
2765         pr_info("%s(): create mhl sysfile\n", __func__);
2766
2767         sec_mhl = class_create(THIS_MODULE, "mhl");
2768         if (IS_ERR(sec_mhl)) {
2769                 pr_err("Failed to create class(sec_mhl)!\n");
2770                 ret = -ENOMEM;
2771                 goto err_exit1c;
2772         }
2773
2774         ret = class_create_file(sec_mhl, &class_attr_ddc_i2c_num);
2775         if (ret) {
2776                 pr_err("Failed to create device file in sysfs entries!\n");
2777                 ret = -ENOMEM;
2778                 goto err_exit2;
2779         }
2780 #ifdef CONFIG_SS_FACTORY
2781         ret = class_create_file(sec_mhl, &class_attr_test_result);
2782         if (ret) {
2783                 pr_err("Failed to create device file in sysfs entries!\n");
2784                 ret = -ENOMEM;
2785                 goto err_exit2a;
2786         }
2787 #endif
2788
2789 #ifdef CONFIG_SII9234_RCP
2790         /* indicate that we generate key events */
2791         set_bit(EV_KEY, input->evbit);
2792         bitmap_fill(input->keybit, KEY_MAX);
2793
2794         sii9234->input_dev = input;
2795         input_set_drvdata(input, sii9234);
2796         input->name = "sii9234_rcp";
2797         input->id.bustype = BUS_I2C;
2798
2799         ret = input_register_device(input);
2800         if (ret < 0) {
2801                 dev_err(&client->dev, "fail to register input device\n");
2802                 goto err_exit2b;
2803         }
2804 #endif
2805
2806 #ifdef CONFIG_MACH_MIDAS
2807         wake_lock_init(&sii9234->wlock, WAKE_LOCK_SUSPEND, "mhl_wake_lock");
2808         pr_debug("%s(): wake lock is initialized.\n", __func__);
2809 #endif
2810
2811         ret = request_threaded_irq(client->irq, NULL, sii9234_irq_thread,
2812                                    IRQF_TRIGGER_RISING | IRQF_ONESHOT,
2813                                    "sii9234", sii9234);
2814         if (ret < 0) {
2815                 printk(KERN_ERR "[ERROR] %s() register thread fail\n",
2816                        __func__);
2817                 ret = -ENOMEM;
2818                 goto err_exit2c;
2819         }
2820
2821         INIT_WORK(&sii9234->msc_work, sii9234_process_msc_work);
2822         disable_irq(client->irq);
2823
2824         return 0;
2825
2826  err_exit2c:
2827 #ifdef CONFIG_SII9234_RCP
2828         input_unregister_device(input);
2829 #endif
2830
2831  err_exit2b:
2832 #ifdef CONFIG_SS_FACTORY
2833         class_remove_file(sec_mhl, &class_attr_test_result);
2834 #endif
2835
2836  err_exit2a:
2837         class_remove_file(sec_mhl, &class_attr_ddc_i2c_num);
2838
2839  err_exit2:
2840         class_destroy(sec_mhl);
2841
2842  err_exit1c:
2843         destroy_workqueue(sii9234_wq);
2844
2845  err_exit1b:
2846         device_remove_file(&(client->dev), &dev_attr_mhl_read_reg);
2847
2848         mutex_destroy(&sii9234->lock);
2849         mutex_destroy(&sii9234->msc_lock);
2850
2851  err_exit1:
2852 #ifdef CONFIG_SII9234_RCP
2853         input_free_device(input);
2854 #endif
2855  err_exit0:
2856         kfree(sii9234);
2857
2858         return ret;
2859 }
2860
2861 static int __devinit sii9234_tpi_i2c_probe(struct i2c_client *client,
2862                                            const struct i2c_device_id *id)
2863 {
2864         struct sii9234_platform_data *pdata = client->dev.platform_data;
2865         if (!pdata) {
2866                 printk(KERN_ERR "[ERROR] %s() fail\n", __func__);
2867                 return -EINVAL;
2868         }
2869         pdata->tpi_client = client;
2870         return 0;
2871 }
2872
2873 static int __devinit sii9234_hdmi_rx_i2c_probe(struct i2c_client *client,
2874                                                const struct i2c_device_id *id)
2875 {
2876         struct sii9234_platform_data *pdata = client->dev.platform_data;
2877         if (!pdata) {
2878                 printk(KERN_ERR "[ERROR] %s() fail\n", __func__);
2879                 return -EINVAL;
2880         }
2881
2882         pdata->hdmi_rx_client = client;
2883         return 0;
2884 }
2885
2886 static int __devinit sii9234_cbus_i2c_probe(struct i2c_client *client,
2887                                             const struct i2c_device_id *id)
2888 {
2889         struct sii9234_platform_data *pdata = client->dev.platform_data;
2890         if (!pdata) {
2891                 printk(KERN_ERR "[ERROR] %s() fail\n", __func__);
2892                 return -EINVAL;
2893         }
2894         pdata->cbus_client = client;
2895         return 0;
2896 }
2897
2898 static int __devexit sii9234_mhl_tx_remove(struct i2c_client *client)
2899 {
2900         return 0;
2901 }
2902
2903 static int __devexit sii9234_tpi_remove(struct i2c_client *client)
2904 {
2905         return 0;
2906 }
2907
2908 static int __devexit sii9234_hdmi_rx_remove(struct i2c_client *client)
2909 {
2910         return 0;
2911 }
2912
2913 static int __devexit sii9234_cbus_remove(struct i2c_client *client)
2914 {
2915         return 0;
2916 }
2917
2918 static const struct i2c_device_id sii9234_mhl_tx_id[] = {
2919         {"sii9234_mhl_tx", 0},
2920         {}
2921 };
2922
2923 static const struct i2c_device_id sii9234_tpi_id[] = {
2924         {"sii9234_tpi", 0},
2925         {}
2926 };
2927
2928 static const struct i2c_device_id sii9234_hdmi_rx_id[] = {
2929         {"sii9234_hdmi_rx", 0},
2930         {}
2931 };
2932
2933 static const struct i2c_device_id sii9234_cbus_id[] = {
2934         {"sii9234_cbus", 0},
2935         {}
2936 };
2937
2938 MODULE_DEVICE_TABLE(i2c, sii9234_mhl_tx_id);
2939 MODULE_DEVICE_TABLE(i2c, sii9234_tpi_id);
2940 MODULE_DEVICE_TABLE(i2c, sii9234_hdmi_rx_id);
2941 MODULE_DEVICE_TABLE(i2c, sii9234_cbus_id);
2942
2943 static struct i2c_driver sii9234_mhl_tx_i2c_driver = {
2944         .driver = {
2945                    .owner = THIS_MODULE,
2946                    .name = "sii9234_mhl_tx",
2947                    },
2948         .id_table = sii9234_mhl_tx_id,
2949         .probe = sii9234_mhl_tx_i2c_probe,
2950         .remove = __devexit_p(sii9234_mhl_tx_remove),
2951         .command = NULL,
2952 };
2953
2954 static struct i2c_driver sii9234_tpi_i2c_driver = {
2955         .driver = {
2956                    .owner = THIS_MODULE,
2957                    .name = "sii9234_tpi",
2958                    },
2959         .id_table = sii9234_tpi_id,
2960         .probe = sii9234_tpi_i2c_probe,
2961         .remove = __devexit_p(sii9234_tpi_remove),
2962 };
2963
2964 static struct i2c_driver sii9234_hdmi_rx_i2c_driver = {
2965         .driver = {
2966                    .owner = THIS_MODULE,
2967                    .name = "sii9234_hdmi_rx",
2968                    },
2969         .id_table = sii9234_hdmi_rx_id,
2970         .probe = sii9234_hdmi_rx_i2c_probe,
2971         .remove = __devexit_p(sii9234_hdmi_rx_remove),
2972 };
2973
2974 static struct i2c_driver sii9234_cbus_i2c_driver = {
2975         .driver = {
2976                    .owner = THIS_MODULE,
2977                    .name = "sii9234_cbus",
2978                    },
2979         .id_table = sii9234_cbus_id,
2980         .probe = sii9234_cbus_i2c_probe,
2981         .remove = __devexit_p(sii9234_cbus_remove),
2982 };
2983
2984 static int __init sii9234_init(void)
2985 {
2986         int ret;
2987
2988         ret = i2c_add_driver(&sii9234_mhl_tx_i2c_driver);
2989         if (ret < 0) {
2990                 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
2991                        __LINE__);
2992                 return ret;
2993         }
2994
2995         ret = i2c_add_driver(&sii9234_tpi_i2c_driver);
2996         if (ret < 0)
2997                 goto err_exit1;
2998
2999         ret = i2c_add_driver(&sii9234_hdmi_rx_i2c_driver);
3000         if (ret < 0)
3001                 goto err_exit2;
3002
3003         ret = i2c_add_driver(&sii9234_cbus_i2c_driver);
3004         if (ret < 0)
3005                 goto err_exit3;
3006
3007         return 0;
3008
3009  err_exit3:
3010         i2c_del_driver(&sii9234_hdmi_rx_i2c_driver);
3011  err_exit2:
3012         i2c_del_driver(&sii9234_tpi_i2c_driver);
3013  err_exit1:
3014         i2c_del_driver(&sii9234_mhl_tx_i2c_driver);
3015         pr_err("i2c_add_driver fail\n");
3016         return ret;
3017 }
3018
3019 static void __exit sii9234_exit(void)
3020 {
3021         i2c_del_driver(&sii9234_cbus_i2c_driver);
3022         i2c_del_driver(&sii9234_hdmi_rx_i2c_driver);
3023         i2c_del_driver(&sii9234_tpi_i2c_driver);
3024         i2c_del_driver(&sii9234_mhl_tx_i2c_driver);
3025 }
3026
3027 module_init(sii9234_init);
3028 module_exit(sii9234_exit);
3029