2 * Copyright (C) 2011 Samsung Electronics
4 * Authors: Adam Hampson <ahampson@sta.samsung.com>
5 * Erik Gilling <konkers@android.com>
7 * Additional contributions by : Shankar Bandal <shankar.b@samsung.com>
8 * Dharam Kumar <dharam.kr@samsung.com>
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.
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.
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
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>
46 #ifndef CONFIG_SII9234_CBUS
47 #define CONFIG_SII9234_CBUS
50 #ifdef CONFIG_SII9234_CBUS
51 #ifndef CONFIG_SII9234_RCP
52 #define CONFIG_SII9234_RCP 1
56 #ifndef CONFIG_SS_FACTORY
57 #define CONFIG_SS_FACTORY 1
60 #ifdef CONFIG_SII9234_RCP
61 #include <linux/sii9234_rcp.h>
62 #include <linux/input.h>
65 #define CONFIG_MHL_DEBUG
68 #ifdef CONFIG_MHL_DEBUG
69 #define pr_debug(fmt, ...) \
71 if (unlikely(mhl_dbg_flag == 1)) { \
72 printk(KERN_INFO fmt, ##__VA_ARGS__); \
77 #define pr_debug(fmt, ...)
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
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
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
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)
116 #define MHL_TX_TMDS_CCTRL 0x80
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
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
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
136 /* MHL TX SYS STAT Registers */
137 #define MHL_TX_SYSSTAT_REG 0x09
139 /* MHL TX SYS STAT Register Bits */
140 #define RSEN_STATUS (1<<2)
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)
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)
155 /* MHL TX INTR1 Register Bits*/
156 #define HPD_CHANGE_INT (1<<6)
157 #define RSEN_CHANGE_INT (1<<5)
159 /* MHL TX INTR1_ENABLE 0x75 Register Bits*/
160 #define HPD_CHANGE_INT_MASK (1<<6)
161 #define RSEN_CHANGE_INT_MASK (1<<5)
163 #define CBUS_CONFIG_REG 0x07
165 #define CBUS_INT_STATUS_1_REG 0x08
166 #define CBUS_INT_1_MASK 0x09
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)
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
187 #define CBUS_INT_STATUS_2_REG 0x1E
189 /* MHL Interrupt Registers */
190 #define CBUS_MHL_INTR_REG_0 0xA0
192 #define CBUS_MHL_INTR_REG_1 0xA1
193 #define MHL_INT_EDID_CHG (1<<1)
195 #define CBUS_MHL_INTR_REG_2 0xA2
196 #define CBUS_MHL_INTR_REG_3 0xA3
198 /* MHL Status Registers */
199 #define CBUS_MHL_STATUS_REG_0 0xB0
200 #define MHL_STATUS_DCAP_READY (1<<0)
202 #define CBUS_MHL_STATUS_REG_1 0xB1
203 #define CBUS_MHL_STATUS_REG_2 0xB2
204 #define CBUS_MHL_STATUS_REG_3 0xB3
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)
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)
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)
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)
230 #define CBUS_INTR_STATUS_1_ENABLE_MASK (MSC_RESP_ABORT_MASK |\
231 MSC_REQ_ABORT_MASK |\
236 #define CBUS_INTR_STATUS_2_ENABLE_MASK (WRT_STAT_RECD_MASK |\
239 #define MHL_INT_EDID_CHG (1<<1)
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)
248 /* CBUS Control Registers*/
249 /* Retry count for all MSC commands*/
250 #define MSC_RETRY_FAIL_LIM_REG 0x1D
252 #define MSC_REQ_ABORT_REASON_REG 0x0D
254 #define MSC_RESP_ABORT_REASON_REG 0x0E
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)
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)
274 /* Set HPD came from Downstream, */
275 #define SET_HPD_DOWNSTREAM (1<<6)
277 /* MHL TX DISC1 Register Bits */
278 #define DISC_EN (1<<0)
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
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)
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)
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
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)
324 /* MHL TX DISC7 0x96 Register Bits
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.
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
337 /* TPI Addr 0x7A Registers */
338 #define TPI_DPD_REG 0x3D
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)
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
361 #define MHL_DEV_CATEGORY_POW_BIT (1<<4)
363 #define MHL_FEATURE_RCP_SUPPORT (1<<0)
364 #define MHL_FEATURE_RAP_SUPPORT (1<<1)
365 #define MHL_FEATURE_SP_SUPPORT (1<<2)
367 #define MHL_STATUS_CLK_MODE_PACKED_PIXEL 0x02
368 #define MHL_STATUS_CLK_MODE_NORMAL 0x03
370 #define MHL_STATUS_PATH_ENABLED 0x08
371 #define MHL_STATUS_PATH_DISABLED 0x00
373 #define MHL_STATUS_REG_CONNECTED_RDY 0x30
375 #define MSC_MAX_QUEUE 16
377 /* page0:0x79 HPD Control Register */
378 #define MHL_HPD_OUT_OVR_EN (1<<4)
379 #define MHL_HPD_OUT_OVR_VAL (1<<5)
381 #define MHL_DEVCAP_DEV_CAT 0x02
382 #define MHL_DEVCAP_FEATURE_FLAG 0x0A
400 STATE_DISCONNECTED = 0,
401 STATE_DISCOVERY_FAILED,
406 enum msc_subcommand {
407 /* MSC_MSG Sub-Command codes */
420 CBUS_WRITE_STAT = 0x60 | 0x80,
422 CBUS_READ_DEVCAP = 0x61,
423 CBUS_GET_STATE = 0x62,
424 CBUS_GET_VENDOR_ID = 0x63,
427 CBUS_SET_CAP_ID = 0x66,
428 CBUS_GET_CAP_ID = 0x67,
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,
437 static struct device *sii9244_mhldev;
439 static struct workqueue_struct *sii9234_wq;
441 static inline bool mhl_state_is_error(enum mhl_state state)
443 return state == STATE_DISCOVERY_FAILED ||
444 state == STATE_CBUS_LOCKOUT;
448 enum cbus_command command;
455 struct sii9234_data {
456 struct sii9234_platform_data *pdata;
457 wait_queue_head_t wq;
458 struct work_struct sii9234_int_work;
461 enum mhl_state state;
462 enum rgnd_state rgnd;
464 atomic_t is_callback_scheduled;
465 #ifdef CONFIG_MACH_MIDAS
466 struct wake_lock wlock;
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];
480 struct input_dev *input_dev;
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);
488 #ifdef CONFIG_SAMSUNG_USE_11PIN_CONNECTOR
489 static int is_mhl_cable_connected(void)
491 return max77693_muic_get_status1_adc1k_value();
495 static int mhl_onoff_ex(struct sii9234_data *sii9234, bool onoff)
499 if (!sii9234 || !sii9234->pdata) {
500 printk(KERN_ERR "[ERROR]sii9234: %s() getting resource is failed\n",
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");
512 pr_info("sii9234: %s(%s)\n", __func__, onoff ? "on" : "off");
514 sii9234->pdata->power_state = onoff; /*save power state*/
516 if (sii9234->pdata->mhl_sel)
517 sii9234->pdata->mhl_sel(onoff);
520 if (sii9234->pdata->hw_onoff)
521 sii9234->pdata->hw_onoff(1);
523 if (sii9234->pdata->hw_reset)
524 sii9234->pdata->hw_reset();
527 pr_info("%s() call __sii9234_power_down\n", __func__);
529 #ifdef CONFIG_SAMSUNG_WORKAROUND_HPD_GLANCE
530 mhl_hpd_handler(false);
533 __sii9234_power_down(sii9234);
535 if (sii9234->pdata->hw_onoff)
536 sii9234->pdata->hw_onoff(0);
538 printk(KERN_ERR "[ERROR]sii9234: %s() hw_onoff is NULL\n",
541 #ifdef CONFIG_SAMSUNG_USE_11PIN_CONNECTOR
542 ret = is_mhl_cable_connected();
544 pr_info("sii9234: %s() mhl still inserted, retry discovery\n",
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",
552 atomic_set(&sii9234->is_callback_scheduled, false);
553 pr_err("[ERROR] %s() is_mhl_cable_connected error : %d\n",
557 atomic_set(&sii9234->is_callback_scheduled, false);
562 mutex_unlock(&sii9234->lock);
566 static int mhl_tx_write_reg(struct sii9234_data *sii9234, unsigned int offset,
570 ret = i2c_smbus_write_byte_data(sii9234->pdata->mhl_tx_client, offset,
573 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
579 static int mhl_tx_read_reg(struct sii9234_data *sii9234, unsigned int offset,
587 ret = i2c_smbus_write_byte(sii9234->pdata->mhl_tx_client, offset);
589 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
593 ret = i2c_smbus_read_byte(sii9234->pdata->mhl_tx_client);
595 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
599 *value = ret & 0x000000FF;
604 static int mhl_tx_set_reg(struct sii9234_data *sii9234, unsigned int offset,
610 ret = mhl_tx_read_reg(sii9234, offset, &value);
612 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
618 ret = mhl_tx_write_reg(sii9234, offset, value);
620 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
627 static int mhl_tx_clear_reg(struct sii9234_data *sii9234, unsigned int offset,
633 ret = mhl_tx_read_reg(sii9234, offset, &value);
635 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
641 ret = mhl_tx_write_reg(sii9234, offset, value);
643 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
650 static int tpi_write_reg(struct sii9234_data *sii9234, unsigned int offset,
654 ret = i2c_smbus_write_byte_data(sii9234->pdata->tpi_client, offset,
657 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
663 static int tpi_read_reg(struct sii9234_data *sii9234, unsigned int offset,
669 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
674 ret = i2c_smbus_write_byte(sii9234->pdata->tpi_client, offset);
676 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
680 ret = i2c_smbus_read_byte(sii9234->pdata->tpi_client);
682 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
686 *value = ret & 0x000000FF;
691 static int hdmi_rx_write_reg(struct sii9234_data *sii9234, unsigned int offset,
695 ret = i2c_smbus_write_byte_data(sii9234->pdata->hdmi_rx_client, offset,
698 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
704 static int hdmi_rx_read_reg(struct sii9234_data *sii9234, unsigned int offset,
710 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
714 ret = i2c_smbus_write_byte(sii9234->pdata->hdmi_rx_client, offset);
716 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
720 ret = i2c_smbus_read_byte(sii9234->pdata->hdmi_rx_client);
722 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
726 *value = ret & 0x000000FF;
731 static int cbus_write_reg(struct sii9234_data *sii9234, unsigned int offset,
735 ret = i2c_smbus_write_byte_data(sii9234->pdata->cbus_client, offset,
738 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
744 static int cbus_read_reg(struct sii9234_data *sii9234, unsigned int offset,
750 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
754 ret = i2c_smbus_write_byte(sii9234->pdata->cbus_client, offset);
756 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
760 ret = i2c_smbus_read_byte(sii9234->pdata->cbus_client);
762 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
766 *value = ret & 0x000000FF;
771 static int cbus_set_reg(struct sii9234_data *sii9234, unsigned int offset,
777 ret = cbus_read_reg(sii9234, offset, &value);
779 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
785 ret = cbus_write_reg(sii9234, offset, value);
787 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
794 static int mhl_wake_toggle(struct sii9234_data *sii9234,
795 unsigned long high_period,
796 unsigned long low_period)
800 /* These bits are not documented. */
802 mhl_tx_set_reg(sii9234, MHL_TX_DISC_CTRL7_REG, (1<<7) | (1<<6));
804 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
809 usleep_range(high_period * USEC_PER_MSEC, high_period * USEC_PER_MSEC);
812 mhl_tx_clear_reg(sii9234, MHL_TX_DISC_CTRL7_REG, (1<<7) | (1<<6));
814 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
819 usleep_range(low_period * USEC_PER_MSEC, low_period * USEC_PER_MSEC);
824 static int mhl_send_wake_pulses(struct sii9234_data *sii9234)
828 ret = mhl_wake_toggle(sii9234, T_SRC_WAKE_PULSE_WIDTH_1,
829 T_SRC_WAKE_PULSE_WIDTH_1);
831 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
836 ret = mhl_wake_toggle(sii9234, T_SRC_WAKE_PULSE_WIDTH_1,
837 T_SRC_WAKE_PULSE_WIDTH_2);
839 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
844 ret = mhl_wake_toggle(sii9234, T_SRC_WAKE_PULSE_WIDTH_1,
845 T_SRC_WAKE_PULSE_WIDTH_1);
847 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
852 ret = mhl_wake_toggle(sii9234, T_SRC_WAKE_PULSE_WIDTH_1,
853 T_SRC_WAKE_TO_DISCOVER);
855 printk(KERN_ERR "[ERROR]sii9234: %s():%d failed !\n", __func__,
863 static int sii9234_cbus_reset(struct sii9234_data *sii9234)
869 ret = mhl_tx_set_reg(sii9234, MHL_TX_SRST, 0x03);
873 usleep_range(2000, 3000);
875 ret = mhl_tx_clear_reg(sii9234, MHL_TX_SRST, 0x03);
879 for (idx = 0 ; idx < 4 ; idx++) {
880 cbus_write_reg(sii9234, 0xE0 + idx, 0xFF);
881 cbus_write_reg(sii9234, 0xF0 + idx, 0xFF);
884 /* Adjust interrupt mask everytime reset is performed.*/
885 ret = cbus_write_reg(sii9234, CBUS_INT_1_MASK, 0);
887 printk(KERN_ERR "[ERROR] %s() write CBUS_INTR1_ENABLE_REG fail\n",
892 ret = cbus_write_reg(sii9234, CBUS_INT_2_MASK, 0);
894 printk(KERN_ERR "[ERROR] %s() write CBUS_INTR2_ENABLE_REG fail\n",
902 /* require to chek mhl imformation of samsung in cbus_init_register*/
903 static int sii9234_cbus_init(struct sii9234_data *sii9234)
907 pr_debug("%s()\n", __func__);
908 cbus_write_reg(sii9234, 0x07, 0xF2);
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);
915 cbus_write_reg(sii9234, 0x1C, 0x01);
916 cbus_write_reg(sii9234, 0x1D, 0x0F);
918 cbus_write_reg(sii9234, 0x44, 0x02);
920 cbus_write_reg(sii9234, 0x31, 0x0D);
921 cbus_write_reg(sii9234, 0x22, 0x01);
922 cbus_write_reg(sii9234, 0x30, 0x01);
924 /* Setup our devcap*/
925 cbus_write_reg(sii9234, 0x80, 0x00);/*To meet cts 6.3.10.1 spec*/
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);
943 cbus_read_reg(sii9234, 0x31, &value);
945 cbus_write_reg(sii9234, 0x31, value);
947 cbus_write_reg(sii9234, 0x30, 0x01);
949 cbus_read_reg(sii9234, 0x3C, &value);
952 cbus_write_reg(sii9234, 0x3C, value);
954 cbus_read_reg(sii9234, 0x22, &value);
957 cbus_write_reg(sii9234, 0x22, value);
959 cbus_read_reg(sii9234, 0x2E, &value);
961 cbus_write_reg(sii9234, 0x2E, value);
963 cbus_write_reg(sii9234, CBUS_INT_1_MASK, 0);
964 cbus_write_reg(sii9234, CBUS_INT_2_MASK, 0);
969 static void force_usb_id_switch_open(struct sii9234_data *sii9234)
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);
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));
985 static void release_usb_id_switch_open(struct sii9234_data *sii9234)
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);
993 /* Enable CBUS discovery*/
994 mhl_tx_set_reg(sii9234, MHL_TX_DISC_CTRL1_REG, (1<<0));
997 #ifdef CONFIG_SII9234_CBUS
998 static void cbus_req_abort_error(struct sii9234_data *sii9234)
1000 u8 abort_reason = 0;
1002 pr_debug("sii9234: %s() MSC Request Aborted:", __func__);
1004 cbus_read_reg(sii9234, MSC_REQ_ABORT_REASON_REG, &abort_reason);
1005 cbus_write_reg(sii9234, MSC_REQ_ABORT_REASON_REG, 0xff);
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",
1029 static void cbus_resp_abort_error(struct sii9234_data *sii9234)
1031 u8 abort_reason = 0;
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);
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");
1048 static bool cbus_ddc_abort_error(struct sii9234_data *sii9234)
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",
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 */
1069 pr_debug("sii9234: %s() DDC abort interrupt\n", __func__);
1074 #ifdef CONFIG_SII9234_RCP
1075 static void rcp_key_report(struct sii9234_data *sii9234, u8 key)
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);
1083 static void cbus_process_rcp_key(struct sii9234_data *sii9234, u8 key)
1085 u8 offset, data_2 = 0;
1087 if (code[key].valid) {
1088 /* Report the key */
1089 rcp_key_report(sii9234, key);
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.
1103 sii9234_enqueue_msc_work(sii9234, CBUS_MSC_MSG, offset, key, data_2);
1106 static void cbus_process_rap_key(struct sii9234_data *sii9234, u8 key)
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);
1113 sii9234_enqueue_msc_work(sii9234, CBUS_MSC_MSG, MSG_RAPK, 0x0, 0x0);
1117 * Incoming MSC_MSG : RCP/RAP/RCPK/RCPE/RAPK commands
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.
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.
1127 static void cbus_handle_msc_msg(struct sii9234_data *sii9234)
1131 if (sii9234->state != STATE_ESTABLISHED) {
1132 pr_debug("sii9234: %s(): invalid MHL state\n", __func__);
1136 cbus_read_reg(sii9234, CBUS_MSC_MSG_CMD_IN, &cmd_code);
1137 cbus_read_reg(sii9234, CBUS_MSC_MSG_DATA_IN, &key);
1139 pr_debug("sii9234: %s(): cmd_code:%d, key:%d\n", __func__,
1144 pr_debug("sii9234: %s(): RCP Arrived. KEY CODE:%d\n",
1146 cbus_process_rcp_key(sii9234, key);
1149 pr_debug("sii9234: %s(): RAP Arrived\n", __func__);
1150 cbus_process_rap_key(sii9234, key);
1153 pr_debug("sii9234: %s(): RCPK Arrived\n", __func__);
1156 pr_debug("sii9234: %s(): RCPE Arrived\n", __func__);
1159 pr_debug("sii9234: %s(): RAPK Arrived\n", __func__);
1162 pr_debug("sii9234: %s(): MAC error\n", __func__);
1163 sii9234_enqueue_msc_work(sii9234, CBUS_GET_MSC_ERR_CODE,
1168 #endif /* CONFIG_SII9234_RCP */
1170 void mhl_path_enable(struct sii9234_data *sii9234, bool path_en)
1172 pr_debug("sii9234: %s(): mhl_path_enable MHL_STATUS_PATH %s\n",
1173 __func__, path_en ? "ENABLED" : "DISABLED");
1176 sii9234->link_mode |= MHL_STATUS_PATH_ENABLED;
1178 sii9234->link_mode &= ~MHL_STATUS_PATH_ENABLED;
1180 sii9234_enqueue_msc_work(sii9234, CBUS_WRITE_STAT,
1181 CBUS_LINK_CONTROL_2_REG, sii9234->link_mode, 0x0);
1184 static void cbus_handle_wrt_stat_recd(struct sii9234_data *sii9234)
1186 u8 status_reg0, status_reg1;
1188 pr_debug("sii9234: %s(): CBUS WRT_STAT_RECD\n", __func__);
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.
1196 * Note that this is not documented properly in the PRM.
1199 cbus_read_reg(sii9234, CBUS_MHL_STATUS_REG_0, &status_reg0);
1200 cbus_write_reg(sii9234, CBUS_MHL_STATUS_REG_0, 0xFF);
1202 cbus_read_reg(sii9234, CBUS_MHL_STATUS_REG_1, &status_reg1);
1203 cbus_write_reg(sii9234, CBUS_MHL_STATUS_REG_1, 0xFF);
1205 pr_debug("sii9234: %s(): STATUS_REG0 : [%d];STATUS_REG1 : [%d]\n",
1206 __func__, status_reg0, status_reg1);
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);
1216 if (status_reg0 & MHL_STATUS_DCAP_READY) {
1217 pr_debug("sii9234: %s(): DEV CAP READY\n", __func__);
1219 sii9234->msc_ready = true;
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);
1225 pr_debug("sii9234: %s(): DEV CAP READY feature flag\n",
1227 sii9234_enqueue_msc_work(sii9234, CBUS_READ_DEVCAP,
1228 MHL_DEVCAP_FEATURE_FLAG, 0x0, 0x0);
1232 static void cbus_handle_edid_change(struct sii9234_data *sii9234)
1234 /* Enable Overriding HPD OUT */
1235 mhl_tx_set_reg(sii9234, MHL_TX_INT_CTRL_REG, (1<<4));
1238 * As per HDMI specification to indicate EDID change
1239 * in TV (or sink), we need to toggle HPD line.
1243 mhl_tx_clear_reg(sii9234, MHL_TX_INT_CTRL_REG, (1<<5));
1245 /* A SET_HPD command shall not follow a CLR_HPD command
1246 * within less than THPD_WIDTH(50ms).
1248 msleep(T_HPD_WIDTH);
1250 /* HPD OUT = High */
1251 mhl_tx_set_reg(sii9234, MHL_TX_INT_CTRL_REG, (1<<5));
1253 /* Disable Overriding of HPD OUT */
1254 mhl_tx_clear_reg(sii9234, MHL_TX_INT_CTRL_REG, (1<<4));
1257 static void cbus_handle_set_int_recd(struct sii9234_data *sii9234)
1259 u8 intr_reg0, intr_reg1, value;
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);
1265 cbus_read_reg(sii9234, CBUS_MHL_INTR_REG_1, &intr_reg1);
1266 cbus_write_reg(sii9234, CBUS_MHL_INTR_REG_1, intr_reg1);
1268 cbus_read_reg(sii9234, CBUS_MHL_INTR_REG_2, &value);
1269 cbus_write_reg(sii9234, CBUS_MHL_INTR_REG_2, value);
1271 cbus_read_reg(sii9234, CBUS_MHL_INTR_REG_3, &value);
1272 cbus_write_reg(sii9234, CBUS_MHL_INTR_REG_3, value);
1274 pr_debug("sii9234: %s(): INTR_REG0 : [%d]; INTR_REG1 : [%d]\n",
1275 __func__, intr_reg0, intr_reg1);
1277 if (intr_reg0 & MHL_INT_DCAP_CHG) {
1278 pr_debug("sii9234: %s(): IHL_INT_DCAP_CHG\n", __func__);
1280 sii9234_enqueue_msc_work(sii9234, CBUS_READ_DEVCAP,
1281 MHL_DEVCAP_DEV_CAT, 0x0, 0x0);
1283 sii9234_enqueue_msc_work(sii9234, CBUS_READ_DEVCAP,
1284 MHL_DEVCAP_FEATURE_FLAG, 0x0, 0x0);
1287 if (intr_reg0 & MHL_INT_DSCR_CHG)
1288 pr_debug("sii9234: %s(): IHL_INT_DSCR_CHG\n", __func__);
1290 if (intr_reg0 & MHL_INT_REQ_WRT) {
1291 pr_debug("sii9234: %s(): MHL_INT_REQ_WRT\n", __func__);
1293 sii9234_enqueue_msc_work(sii9234, CBUS_SET_INT,
1294 MHL_RCHANGE_INT, MHL_INT_GRT_WRT, 0x0);
1297 if (intr_reg0 & MHL_INT_GRT_WRT)
1298 pr_debug("sii9234: %s(): MHL_INT_GRT_WRT\n", __func__);
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);
1305 #endif /* CONFIG_SII9234_CBUS */
1307 static int sii9234_power_init(struct sii9234_data *sii9234)
1311 /* Force the SiI9234 into the D0 state. */
1312 ret = tpi_write_reg(sii9234, TPI_DPD_REG, 0x3F);
1314 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1319 /* Enable TxPLL Clock */
1320 ret = hdmi_rx_write_reg(sii9234, HDMI_RX_TMDS_CLK_EN_REG, 0x01);
1322 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1327 /* Enable Tx Clock Path & Equalizer */
1328 ret = hdmi_rx_write_reg(sii9234, HDMI_RX_TMDS_CH_EN_REG, 0x15);
1330 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1336 ret = mhl_tx_write_reg(sii9234, 0x08, 0x35);
1338 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1346 static int sii9234_hdmi_init(struct sii9234_data *sii9234)
1349 /* Analog PLL Control
1350 * bits 5:4 = 2b00 as per characterization team.
1352 ret = hdmi_rx_write_reg(sii9234, HDMI_RX_TMDS0_CCTRL1_REG, 0xC1);
1354 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1360 ret = hdmi_rx_write_reg(sii9234, HDMI_RX_PLL_CALREFSEL_REG, 0x03);
1362 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1368 ret = hdmi_rx_write_reg(sii9234, HDMI_RX_PLL_VCOCAL_REG, 0x20);
1370 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1376 ret = hdmi_rx_write_reg(sii9234, HDMI_RX_EQ_DATA0_REG, 0x8A);
1378 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1384 ret = hdmi_rx_write_reg(sii9234, HDMI_RX_EQ_DATA1_REG, 0x6A);
1386 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1392 ret = hdmi_rx_write_reg(sii9234, HDMI_RX_EQ_DATA2_REG, 0xAA);
1394 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1400 ret = hdmi_rx_write_reg(sii9234, HDMI_RX_EQ_DATA3_REG, 0xCA);
1402 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1408 ret = hdmi_rx_write_reg(sii9234, HDMI_RX_EQ_DATA4_REG, 0xEA);
1410 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1416 ret = hdmi_rx_write_reg(sii9234, HDMI_RX_TMDS_ZONE_CTRL_REG, 0xA0);
1418 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1423 /* PLL Mode Value */
1424 ret = hdmi_rx_write_reg(sii9234, HDMI_RX_TMDS_MODE_CTRL_REG, 0x00);
1426 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1432 /* ret = mhl_tx_write_reg(sii9234, MHL_TX_TMDS_CCTRL, 0x34); */
1433 ret = mhl_tx_write_reg(sii9234, MHL_TX_TMDS_CCTRL, 0x24);
1435 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1440 ret = hdmi_rx_write_reg(sii9234, 0x45, 0x44);
1442 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1447 /* Rx PLL BW ~ 4MHz */
1448 ret = hdmi_rx_write_reg(sii9234, 0x31, 0x0A);
1450 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1455 /* Analog PLL Control
1456 * bits 5:4 = 2b00 as per characterization team.
1461 static int sii9234_mhl_tx_ctl_int(struct sii9234_data *sii9234)
1465 ret = mhl_tx_write_reg(sii9234, MHL_TX_MHLTX_CTL1_REG, 0xD0);
1467 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1472 ret = mhl_tx_write_reg(sii9234, MHL_TX_MHLTX_CTL2_REG, 0xFC);
1474 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1479 ret = mhl_tx_write_reg(sii9234, MHL_TX_MHLTX_CTL4_REG, 0xEB);
1481 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1486 ret = mhl_tx_write_reg(sii9234, MHL_TX_MHLTX_CTL7_REG, 0x0C);
1488 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
1496 static void __sii9234_power_down(struct sii9234_data *sii9234)
1498 disable_irq_nosync(sii9234->pdata->mhl_tx_client->irq);
1500 if (sii9234->claimed) {
1501 if (sii9234->pdata->vbus_present)
1502 sii9234->pdata->vbus_present(false);
1505 sii9234->state = STATE_DISCONNECTED;
1506 sii9234->claimed = false;
1508 /* power down mhl intenal modules */
1509 tpi_write_reg(sii9234, TPI_DPD_REG, 0);
1512 /* Must call with sii9234->lock held */
1513 static int sii9234_msc_req_locked(struct sii9234_data *sii9234,
1514 struct msc_packet *msc_pkt)
1519 if (sii9234->state != STATE_ESTABLISHED)
1522 init_completion(&sii9234->msc_complete);
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);
1527 switch (msc_pkt->command) {
1529 case CBUS_WRITE_STAT:
1530 start_command = START_WRITE_STAT_INT;
1533 cbus_write_reg(sii9234, CBUS_MSC_SECOND_DATA_OUT,
1535 cbus_write_reg(sii9234, CBUS_MSC_OFFSET_REG, msc_pkt->command);
1537 start_command = START_MSC_MSG;
1539 case CBUS_READ_DEVCAP:
1540 start_command = START_READ_DEVCAP;
1542 case CBUS_WRITE_BURST:
1543 start_command = START_WRITE_BURST;
1545 case CBUS_GET_STATE:
1546 case CBUS_GET_VENDOR_ID:
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);
1555 start_command = START_MSC_RESERVED;
1558 pr_info("%s() invalid msc command(%d)\n",
1559 __func__, msc_pkt->command);
1563 cbus_write_reg(sii9234, CBUS_MSC_COMMAND_START, start_command);
1565 mutex_unlock(&sii9234->lock);
1566 ret = wait_for_completion_timeout(&sii9234->msc_complete,
1567 msecs_to_jiffies(500));
1569 printk(KERN_ERR "[ERROR] %s() MSC_REQ_DONE timeout\n",
1572 mutex_lock(&sii9234->lock);
1574 return ret ? 0 : -EIO;
1577 void sii9234_process_msc_work(struct work_struct *work)
1579 struct msc_packet msc_pkt;
1582 struct sii9234_data *sii9234 = container_of(work,
1583 struct sii9234_data,
1586 mutex_lock(&sii9234->msc_lock);
1587 mutex_lock(&sii9234->lock);
1589 pr_info("%s()\n", __func__);
1591 if (!sii9234->msc_queue[sii9234->msc_front].sent) {
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;
1599 sii9234->msc_queue[sii9234->msc_front].sent = true;
1602 ret = sii9234_msc_req_locked(sii9234, &msc_pkt);
1604 pr_info("%s(): msc_req_locked error %d\n", __func__,
1609 /* MSC_REQ_DONE received */
1610 switch (msc_pkt.command) {
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);
1618 case CBUS_WRITE_STAT:
1622 case CBUS_WRITE_BURST:
1624 case CBUS_READ_DEVCAP:
1625 ret = cbus_read_reg(sii9234,
1626 CBUS_MSC_FIRST_DATA_IN, &val);
1630 sii9234->devcap[msc_pkt.offset] = val;
1637 mutex_unlock(&sii9234->lock);
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--;
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);
1651 mutex_unlock(&sii9234->msc_lock);
1654 static void sii9234_enqueue_msc_work(struct sii9234_data *sii9234, u8 command,
1655 u8 offset, u8 data_1, u8 data_2)
1659 next_idx = (sii9234->msc_rear + 1) % MSC_MAX_QUEUE;
1661 if (next_idx == sii9234->msc_front) {
1662 pr_info("%s queue full\n", __func__);
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;
1672 sii9234->msc_rear = next_idx;
1674 pr_info("%s() msc work schedule\n", __func__);
1675 schedule_work(&sii9234->msc_work);
1678 /* Must call with sii9234->lock held */
1679 static int sii9234_devcap_read_locked(struct sii9234_data *sii9234, u8 offset)
1683 struct msc_packet msc_pkt;
1688 msc_pkt.command = CBUS_READ_DEVCAP;
1689 msc_pkt.offset = offset;
1691 ret = sii9234_msc_req_locked(sii9234, &msc_pkt);
1696 ret = cbus_read_reg(sii9234, CBUS_MSC_FIRST_DATA_IN, &val);
1704 void sii9234_mhl_detection_sched(void)
1706 struct sii9234_data *sii9234 = dev_get_drvdata(sii9244_mhldev);
1707 printk(KERN_INFO "%s()\n", __func__);
1709 if (!sii9234 || !sii9234->pdata) {
1711 "[ERROR] %s() getting resource is failed\n", __func__);
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));
1720 pr_debug("%s(): detection callback is already scheduled.\n",
1723 mutex_unlock(&sii9234->lock);
1725 EXPORT_SYMBOL(sii9234_mhl_detection_sched);
1727 static void sii9234_detection_callback(struct work_struct *p)
1729 struct sii9234_data *sii9234;
1734 printk(KERN_INFO "%s()\n", __func__);
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__);
1742 mhl_onoff_ex(sii9234, true);
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;
1753 /* Set the board configuration so the SiI9234 has access to the
1754 * external connector.
1757 if (sii9234->pdata == NULL) {
1758 printk(KERN_ERR "[ERROR] %s():%d sii9234->pdata error!!\n",
1759 __func__, __LINE__);
1763 ret = sii9234_power_init(sii9234);
1765 printk(KERN_ERR "[ERROR] %s():%d sii9234_power_init failed !\n",
1766 __func__, __LINE__);
1770 ret = sii9234_cbus_reset(sii9234);
1772 printk(KERN_ERR "[ERROR] %s():%d sii9234_cbus_reset failed !\n",
1773 __func__, __LINE__);
1777 ret = sii9234_hdmi_init(sii9234);
1779 printk(KERN_ERR "[ERROR] %s():%d sii9234_hdmi_init failed !\n",
1780 __func__, __LINE__);
1784 ret = sii9234_mhl_tx_ctl_int(sii9234);
1787 "[ERROR] %s():%d sii9234_mhl_tx_ctl_init failed !\n",
1788 __func__, __LINE__);
1792 /* Enable HDCP Compliance safety */
1793 ret = mhl_tx_write_reg(sii9234, 0x2B, 0x01);
1795 printk(KERN_ERR "[ERROR] %s():%d mhl_tx_write_reg failed !\n",
1796 __func__, __LINE__);
1800 /* CBUS discovery cycle time for each drive and float = 150us */
1801 ret = mhl_tx_read_reg(sii9234, MHL_TX_DISC_CTRL1_REG, &value);
1803 printk(KERN_ERR "[ERROR] %s():%d mhl_tx_read_reg failed !\n",
1804 __func__, __LINE__);
1811 ret = mhl_tx_write_reg(sii9234, MHL_TX_DISC_CTRL1_REG, value);
1813 printk(KERN_ERR "[ERROR] %s():%d mhl_tx_write_reg failed !\n",
1814 __func__, __LINE__);
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);
1824 printk(KERN_ERR "[ERROR] %s():%d Clear bit 6 failed !\n",
1825 __func__, __LINE__);
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);
1835 "[ERROR] %s():%d write MHL_TX_DISC_CTRL5_REG failed !\n",
1836 __func__, __LINE__);
1840 /* set bit 2 and 3, which is Initiator Timeout */
1841 ret = cbus_read_reg(sii9234, CBUS_LINK_CONTROL_2_REG, &value);
1844 "[ERROR] %s():%d read CBUS_LINK_CONTROL_2_REG failed !\n",
1845 __func__, __LINE__);
1851 ret = cbus_write_reg(sii9234, CBUS_LINK_CONTROL_2_REG, value);
1854 "[ERROR] %s():%d write CBUS_LINK_CONTROL_2_REG failed !\n",
1855 __func__, __LINE__);
1859 ret = mhl_tx_write_reg(sii9234, MHL_TX_MHLTX_CTL6_REG, 0xA0);
1862 "[ERROR] %s():%d write MHL_TX_MHLTX_CTL6_REG failed !\n",
1863 __func__, __LINE__);
1867 /* RGND & single discovery attempt (RGND blocking) */
1868 ret = mhl_tx_write_reg(sii9234, MHL_TX_DISC_CTRL6_REG, 0x71);
1871 "[ERROR] %s():%d write MHL_TX_DISC_CTRL6_REG failed !\n",
1872 __func__, __LINE__);
1876 /* Use VBUS path of discovery state machine */
1877 ret = mhl_tx_write_reg(sii9234, MHL_TX_DISC_CTRL8_REG, 0x0);
1880 "[ERROR] %s():%d write MHL_TX_DISC_CTRL8_REG failed !\n",
1881 __func__, __LINE__);
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)
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);
1898 "[ERROR] %s():%d set MHL_TX_DISC_CTRL3_REG failed !\n",
1899 __func__, __LINE__);
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);
1908 "[ERROR] %s():%d set MHL_TX_DISC_CTRL4_REG failed !\n",
1909 __func__, __LINE__);
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);
1917 /* Configure the interrupt as active high */
1919 mhl_tx_clear_reg(sii9234, MHL_TX_INT_CTRL_REG, (1 << 2) | (1 << 1));
1922 "[ERROR] %s():%d clear MHL_TX_INT_CTRL_REG failed !\n",
1923 __func__, __LINE__);
1929 ret = mhl_tx_write_reg(sii9234, MHL_TX_DISC_CTRL1_REG, 0x27);
1932 "[ERROR] %s():%dwrite MHL_TX_DISC_CTRL1_REG failed !\n",
1933 __func__, __LINE__);
1937 sii9234_cbus_init(sii9234);
1939 /* Enable Auto soft reset on SCDT = 0 */
1940 ret = mhl_tx_write_reg(sii9234, 0x05, 0x04);
1942 printk(KERN_ERR "[ERROR] %s():%d write 0x05 failed !\n",
1943 __func__, __LINE__);
1947 /* HDMI Transcode mode enable */
1948 ret = mhl_tx_write_reg(sii9234, 0x0D, 0x1C);
1951 "[ERROR] %s():%dHDMI Transcode mode enable failed !\n",
1952 __func__, __LINE__);
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);
1961 "[ERROR] %s():%d write MHL_TX_INTR4_ENABLE_REG failed !\n",
1962 __func__, __LINE__);
1966 ret = mhl_tx_write_reg(sii9234, MHL_TX_INTR1_ENABLE_REG,
1967 RSEN_CHANGE_INT_MASK);
1970 "[ERROR] %s():%dwrite MHL_TX_INTR1_ENABLE_REG failed !\n",
1971 __func__, __LINE__);
1975 ret = cbus_write_reg(sii9234, CBUS_INT_1_MASK,
1976 CBUS_INTR_STATUS_1_ENABLE_MASK);
1979 "[ERROR] %s() cbus register init failed !\n",
1984 ret = cbus_write_reg(sii9234, CBUS_INT_2_MASK,
1985 CBUS_INTR_STATUS_2_ENABLE_MASK);
1989 /* this point is very importand before megsure RGND impedance*/
1990 force_usb_id_switch_open(sii9234);
1992 mhl_tx_clear_reg(sii9234, MHL_TX_DISC_CTRL4_REG,
1993 (1<<7) | (1<<6) | (1<<5) | (1<<4));
1995 release_usb_id_switch_open(sii9234);
1997 //printk("[%d] %s\n", __LINE__, __func__);
2000 pr_debug("%s(): waiting for RGND measurement\n", __func__);
2001 enable_irq(sii9234->pdata->mhl_tx_client->irq);
2003 /* SiI9244 Programmer's Reference Section 2.4.3
2004 * State : RGND Ready
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));
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__);
2019 if (sii9234->rgnd != RGND_1K) {
2020 printk(KERN_ERR "[ERROR] %s():%d rgnd impedance failed !\n",
2021 __func__, __LINE__);
2025 mutex_unlock(&sii9234->lock);
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));
2032 mutex_lock(&sii9234->lock);
2035 "[ERROR] %s():%d wait detection state failed !\n",
2036 __func__, __LINE__);
2040 if (sii9234->state == STATE_DISCONNECTED) {
2042 "[ERROR] %s():%d sii9234->state is STATE_DISCONNECTED !\n",
2043 __func__, __LINE__);
2047 if (sii9234->state == STATE_DISCOVERY_FAILED) {
2049 "[ERROR] %s():%d STATE_DISCOVERY_FAILED failed !\n",
2050 __func__, __LINE__);
2054 if (mhl_state_is_error(sii9234->state)) {
2055 printk(KERN_ERR "[ERROR] %s():%d mhl_state_is_error failed !\n",
2056 __func__, __LINE__);
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);
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__);
2074 ret = mhl_tx_read_reg(sii9234, MHL_TX_SYSSTAT_REG,
2076 if (!(ret && (value & RSEN_STATUS))) {
2077 pr_debug("%s(): RSEN is still low\n", __func__);
2082 sii9234->rsen = value & RSEN_STATUS;
2084 pr_info("%s(): RSEN OK\n", __func__);
2086 #ifdef CONFIG_SAMSUNG_WORKAROUND_HPD_GLANCE
2087 mhl_hpd_handler(true);
2090 mutex_unlock(&sii9234->lock);
2092 ret = wait_event_timeout(sii9234->wq, sii9234->msc_ready,
2093 msecs_to_jiffies(2000));
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);
2104 mutex_unlock(&sii9234->msc_lock);
2107 sii9234->devcap[i] = ret;
2108 mutex_unlock(&sii9234->msc_lock);
2112 print_hex_dump(KERN_DEBUG, "sii9234: devcap = ",
2113 DUMP_PREFIX_NONE, 16, 1,
2114 sii9234->devcap, 16, false);
2117 printk(KERN_ERR"%s() msc not ready : ret=%d, msc_ready=%d\n",
2118 __func__, ret, sii9234->msc_ready);
2120 mutex_lock(&sii9234->lock);
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.
2126 if (sii9234->state != STATE_ESTABLISHED) {
2127 printk(KERN_ERR"%s() state is wrong : 0x%x\n",
2128 __func__, sii9234->state);
2132 pr_info("%s(): connection established\n", __func__);
2134 sii9234->claimed = true;
2135 mutex_unlock(&sii9234->lock);
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)");
2149 pr_info("%s() mhl power off\n", __func__);
2150 mutex_unlock(&sii9234->lock);
2151 mhl_onoff_ex(sii9234, false);
2153 pr_debug("%s(): dectection callback finished\n", __func__);
2157 #ifdef CONFIG_SII9234_CBUS
2159 static int sii9234_cbus_irq(struct sii9234_data *sii9234)
2161 u8 cbus_intr1, cbus_intr2;
2162 u8 mhl_intr0, mhl_intr1;
2163 u8 mhl_status0, mhl_status1, mhl_status2, mhl_status3;
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);
2176 pr_debug("%s(): intr %02x %02x\n", __func__, cbus_intr1, cbus_intr2);
2178 if (cbus_intr1 & MSC_RESP_ABORT)
2179 cbus_resp_abort_error(sii9234);
2181 if (cbus_intr1 & MSC_REQ_ABORT)
2182 cbus_req_abort_error(sii9234);
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__);
2192 if (cbus_intr1 & MSC_REQ_DONE) {
2193 pr_debug("%s(): msc request done\n", __func__);
2194 complete(&sii9234->msc_complete);
2197 if (cbus_intr1 & MSC_MSG_RECD) {
2198 pr_debug("%s(): msc msg received\n", __func__);
2199 cbus_handle_msc_msg(sii9234);
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;
2208 if (cbus_intr2 & SET_INT_RECD)
2209 cbus_handle_set_int_recd(sii9234);
2211 if (cbus_intr2 & WRT_BURST_RECD)
2212 pr_debug("%s(): write burst received\n", __func__);
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);
2226 mhl_onoff_ex(sii9234, false);
2231 #endif /* CONFIG_SII9234_CBUS */
2233 static u8 sii9234_tmds_control(struct sii9234_data *sii9234, bool enable)
2239 ret = mhl_tx_set_reg(sii9234, MHL_TX_TMDS_CCTRL, (1<<4));
2241 printk(KERN_ERR "%s() mhl_tx_set_reg fail\n", __func__);
2244 pr_debug("%s() MHL HPD High, enabled TMDS\n",
2246 ret = mhl_tx_set_reg(sii9234, MHL_TX_INT_CTRL_REG,
2247 MHL_HPD_OUT_OVR_EN | MHL_HPD_OUT_OVR_VAL);
2250 "%s() mhl_tx_set_reg fail\n", __func__);
2254 ret = mhl_tx_clear_reg(sii9234, MHL_TX_TMDS_CCTRL, (1<<4));
2257 "%s() mhl_tx_clear_reg fail\n", __func__);
2260 pr_debug("%s() MHL HPD low, disabled TMDS\n", __func__);
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);
2267 "%s() clear MHL_TX_INT_CTRL_REG fail\n",
2271 ret = mhl_tx_set_reg(sii9234, MHL_TX_INT_CTRL_REG,
2272 MHL_HPD_OUT_OVR_EN);
2275 "%s() set MHL_TX_INT_CTRL_REG fail\n",
2279 pr_info("%s(): MHL HPD low, disabled TMDS\n", __func__);
2285 static irqreturn_t sii9234_irq_thread(int irq, void *data)
2287 struct sii9234_data *sii9234 = data;
2289 u8 intr1, intr4, value;
2290 u8 intr1_en, intr4_en;
2291 u8 mhl_poweroff = 0;
2294 mutex_lock(&sii9234->lock);
2295 ret = mhl_tx_read_reg(sii9234, MHL_TX_INTR1_REG, &intr1);
2298 "[ERROR] %s():%d read MHL_TX_INTR1_REG failed !\n",
2299 __func__, __LINE__);
2300 goto i2c_error_exit;
2303 ret = mhl_tx_read_reg(sii9234, MHL_TX_INTR4_REG, &intr4);
2306 "[ERROR] %s():%d read MHL_TX_INTR4_REG failed !\n",
2307 __func__, __LINE__);
2308 goto i2c_error_exit;
2311 ret = mhl_tx_read_reg(sii9234, MHL_TX_INTR1_ENABLE_REG, &intr1_en);
2314 "[ERROR] %s():%d read MHL_TX_INTR1_ENABLE_REG failed !\n",
2315 __func__, __LINE__);
2316 goto i2c_error_exit;
2319 ret = mhl_tx_read_reg(sii9234, MHL_TX_INTR4_ENABLE_REG, &intr4_en);
2322 "[ERROR] %s():%d read MHL_TX_INTR4_ENABLE_REG failed !\n",
2323 __func__, __LINE__);
2324 goto i2c_error_exit;
2327 pr_debug("%s(): irq %02x/%02x %02x/%02x\n", __func__, intr1, intr1_en,
2330 if (intr4 & RGND_READY_INT) {
2331 ret = mhl_tx_read_reg(sii9234, MHL_TX_STAT2_REG, &value);
2333 dev_err(&sii9234->pdata->mhl_tx_client->dev,
2334 "STAT2 reg, err %d\n", ret);
2338 switch (value & RGND_INTP_MASK) {
2339 case RGND_INTP_OPEN:
2340 pr_debug("%s(): RGND Open\n", __func__);
2341 sii9234->rgnd = RGND_OPEN;
2344 pr_debug("%s(): RGND 1K\n", __func__);
2345 ret = mhl_tx_set_reg(sii9234, MHL_TX_DISC_CTRL4_REG,
2349 "[ERROR] %s():%d write MHL_TX_DISC_CTRL4_REG failed !\n",
2350 __func__, __LINE__);
2351 goto i2c_error_exit;
2354 ret = mhl_tx_set_reg(sii9234,
2355 MHL_TX_DISC_CTRL6_REG, 0x05);
2358 "[ERROR] %s():%d write MHL_TX_DISC_CTRL6_REG failed !\n",
2359 __func__, __LINE__);
2360 goto i2c_error_exit;
2363 usleep_range(T_SRC_VBUS_CBUS_TO_STABLE * USEC_PER_MSEC,
2364 T_SRC_VBUS_CBUS_TO_STABLE * USEC_PER_MSEC);
2366 ret = mhl_send_wake_pulses(sii9234);
2369 "[ERROR] %s():%d mhl_send_wake_pulses failed !\n",
2370 __func__, __LINE__);
2371 goto i2c_error_exit;
2373 sii9234->rgnd = RGND_1K;
2375 cbus_write_reg(sii9234, CBUS_INT_1_MASK, 0);
2376 cbus_write_reg(sii9234, CBUS_INT_2_MASK, 0);
2379 pr_debug("%s(): RGND 2K\n", __func__);
2380 sii9234->rgnd = RGND_2K;
2382 case RGND_INTP_SHORT:
2383 pr_debug("%s(): RGND Short\n", __func__);
2384 sii9234->rgnd = RGND_SHORT;
2389 if (intr4 & CBUS_LKOUT_INT) {
2390 pr_debug("%s(): CBUS Lockout Interrupt\n", __func__);
2391 sii9234->state = STATE_CBUS_LOCKOUT;
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;
2399 if (intr4 & MHL_EST_INT) {
2400 pr_debug("%s(): mhl est interrupt %d\n", __func__, value);
2402 /* discovery override */
2403 ret = mhl_tx_write_reg(sii9234, MHL_TX_MHLTX_CTL1_REG, 0x10);
2406 "[ERROR] %s():%d write MHL_TX_MHLTX_CTRL1_REG failed !\n",
2407 __func__, __LINE__);
2408 goto i2c_error_exit;
2411 /* increase DDC translation layer timer (byte mode) */
2412 ret = cbus_write_reg(sii9234, 0x07, 0x32);
2415 "[ERROR] %s():%d cbus_write_reg failed !\n",
2416 __func__, __LINE__);
2417 goto i2c_error_exit;
2419 ret = cbus_set_reg(sii9234, 0x44, 1 << 1);
2422 "[ERROR] %s():%d cbus_set_reg failed !\n",
2423 __func__, __LINE__);
2424 goto i2c_error_exit;
2427 /* Keep the discovery enabled. Need RGND interrupt */
2428 ret = mhl_tx_set_reg(sii9234, MHL_TX_DISC_CTRL1_REG, (1 << 0));
2431 "[ERROR] %s():%d mhl_tx_set_reg failed !\n",
2432 __func__, __LINE__);
2433 goto i2c_error_exit;
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);
2441 mhl_tx_write_reg(sii9234, MHL_TX_INTR1_ENABLE_REG,
2442 RSEN_CHANGE_INT_MASK | HPD_CHANGE_INT_MASK);
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);
2451 if (intr1 & HPD_CHANGE_INT) {
2452 ret = cbus_read_reg(sii9234, MSC_REQ_ABORT_REASON_REG, &value);
2454 if (value & SET_HPD_DOWNSTREAM) {
2455 pr_info("%s() hpd high\n", __func__);
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);
2463 ret = sii9234_tmds_control(sii9234, true);
2466 "[ERROR] %s():%d set sii9234_tmds_control\n",
2467 __func__, __LINE__);
2468 goto i2c_error_exit;
2470 pr_debug("%s(): MHL HPD High, enabled TMDS\n",
2474 pr_info("%s(): hpd low\n", __func__);
2476 ret = sii9234_tmds_control(sii9234, false);
2479 "[ERROR] %s():%d set sii9234_tmds_control\n",
2480 __func__, __LINE__);
2481 goto i2c_error_exit;
2486 if (intr1 & RSEN_CHANGE_INT) {
2487 ret = mhl_tx_read_reg(sii9234, MHL_TX_SYSSTAT_REG, &value);
2489 sii9234->rsen = value & RSEN_STATUS;
2491 if (value & RSEN_STATUS) {
2492 pr_info("%s(): MHL cable connected.. RSEN High\n",
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
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,
2507 "[ERROR] %s() read MHL_TX_SYSSTAT_REG\n",
2511 pr_info("%s(): sys_stat: %x ~\n", __func__, value);
2513 if ((value & RSEN_STATUS) == 0) {
2515 "%s() RSEN Really LOW ~\n", __func__);
2517 sii9234_tmds_control(sii9234, false);
2518 mhl_poweroff = true;
2519 goto i2c_error_exit;
2524 #ifdef CONFIG_SII9234_CBUS
2525 if (sii9234->state == STATE_ESTABLISHED)
2526 sii9234_cbus_irq(sii9234);
2530 mhl_tx_write_reg(sii9234, MHL_TX_INTR1_REG, intr1);
2531 mhl_tx_write_reg(sii9234, MHL_TX_INTR4_REG, intr4);
2533 mutex_unlock(&sii9234->lock);
2535 pr_debug("%s(): wake_up\n", __func__);
2536 wake_up(&sii9234->wq);
2541 mutex_unlock(&sii9234->lock);
2543 pr_info("%s(): wake_up\n", __func__);
2544 wake_up(&sii9234->wq);
2547 printk(KERN_INFO "%s() mhl_poweroff\n", __func__);
2548 mhl_onoff_ex(sii9234, false);
2554 #ifdef CONFIG_SS_FACTORY
2556 static ssize_t sysfs_check_mhl_command(struct class *class,
2557 struct class_attribute *attr, char *buf)
2561 struct sii9234_data *sii9234 = dev_get_drvdata(sii9244_mhldev);
2563 if (sii9234->pdata->hw_onoff)
2564 sii9234->pdata->hw_onoff(1);
2566 if (sii9234->pdata->hw_reset)
2567 sii9234->pdata->hw_reset();
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);
2572 if (sii9234->pdata->hw_onoff)
2573 sii9234->pdata->hw_onoff(1);
2575 size = snprintf(buf, 10, "%d\n", sii_id == SII_ID ? 1 : 0);
2581 static CLASS_ATTR(test_result, 0664 , sysfs_check_mhl_command, NULL);
2582 #endif /*config_ss_factory*/
2584 static ssize_t sysfs_sii9234_ddc_i2c_num_show(struct class *class,
2585 struct class_attribute *attr, char *buf)
2588 struct sii9234_data *sii9234 = dev_get_drvdata(sii9244_mhldev);
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);
2597 static CLASS_ATTR(ddc_i2c_num, 0664 , sysfs_sii9234_ddc_i2c_num_show, NULL);
2599 static ssize_t sysfs_mhl_read_reg_show(struct device *dev,
2600 struct device_attribute *attr, char *buf)
2602 pr_info("sii9234: %s()\n", __func__);
2603 return sprintf(buf, "sysfs_mhl_read_reg_show\n");
2607 static ssize_t sysfs_mhl_read_reg_store(struct device *dev,
2608 struct device_attribute *attr,
2609 const char *buf, size_t size)
2611 struct sii9234_data *sii9234 = dev_get_drvdata(sii9244_mhldev);
2613 unsigned int offset;
2617 char *buffer = (char *)buf;
2620 pr_info("sii9234: Error : Unsupported format\n");
2624 if (strnicmp(buf, "mhl", 3) == 0) {
2625 printk(KERN_INFO "sii9234: %s() - mhl start\n", __func__);
2626 sii9234_mhl_detection_sched();
2629 strcpy(dest, strsep(&buffer, ":"));
2630 ret = kstrtouint(dest, 0, &offset);
2632 pr_info("sii9234: Error : Page number\n");
2635 pn = (enum page_num)offset;
2637 strcpy(dest, buffer);
2638 ret = kstrtouint(dest, 0, &offset);
2639 if (ret || offset > 0xff) {
2640 pr_info("sii9234: Error : Offset number\n");
2646 mhl_tx_read_reg(sii9234, offset, &value);
2649 tpi_read_reg(sii9234, offset, &value);
2652 hdmi_rx_read_reg(sii9234, offset, &value);
2655 cbus_read_reg(sii9234, offset, &value);
2658 pr_info("\nsii9234: Error : Out of the page number range\n");
2661 pr_info("sii9234: MHL register Page%d:0x%02x = 0x%02x\n", pn, offset,
2667 static DEVICE_ATTR(mhl_read_reg, S_IRUGO | S_IWUSR,
2668 sysfs_mhl_read_reg_show, sysfs_mhl_read_reg_store);
2670 static DEVICE_ATTR(mhl_read_reg, S_IRUGO, sysfs_mhl_read_reg_show, NULL);
2672 #ifdef CONFIG_MHL_DEBUG
2673 module_param_named(mhl_dbg_flag, mhl_dbg_flag, uint, 0644);
2676 #ifdef CONFIG_MACH_MIDAS
2677 void sii9234_wake_lock(void)
2679 struct sii9234_data *sii9234 = dev_get_drvdata(sii9244_mhldev);
2680 wake_lock(&sii9234->wlock);
2681 pr_debug("%s()\n", __func__);
2683 EXPORT_SYMBOL(sii9234_wake_lock);
2685 void sii9234_wake_unlock(void)
2687 struct sii9234_data *sii9234 = dev_get_drvdata(sii9244_mhldev);
2688 wake_unlock(&sii9234->wlock);
2689 pr_debug("%s()\n", __func__);
2691 EXPORT_SYMBOL(sii9234_wake_unlock);
2694 static int __devinit sii9234_mhl_tx_i2c_probe(struct i2c_client *client,
2695 const struct i2c_device_id *id)
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;
2703 #ifdef CONFIG_SS_FACTORY
2704 struct class *sec_mhl;
2707 #ifdef CONFIG_MHL_DEBUG
2711 printk(KERN_INFO "%s()\n", __func__);
2713 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
2714 printk(KERN_ERR "[ERROR] %s() i2c no function\n", __func__);
2718 sii9234 = kzalloc(sizeof(struct sii9234_data), GFP_KERNEL);
2720 dev_err(&client->dev, "failed to allocate driver data\n");
2724 atomic_set(&sii9234->is_callback_scheduled, false);
2725 #ifdef CONFIG_SII9234_RCP
2726 input = input_allocate_device();
2728 dev_err(&client->dev, "failed to allocate input device.\n");
2734 sii9234->pdata = client->dev.platform_data;
2735 if (!sii9234->pdata) {
2737 printk(KERN_ERR "[ERROR] %s() platform_data is NULL\n",
2741 sii9234->pdata->mhl_tx_client = client;
2743 init_waitqueue_head(&sii9234->wq);
2744 mutex_init(&sii9234->lock);
2745 mutex_init(&sii9234->msc_lock);
2747 i2c_set_clientdata(client, sii9234);
2748 sii9244_mhldev = &client->dev;
2750 sii9234->pdata->init();
2752 ret = device_create_file(&(client->dev), &dev_attr_mhl_read_reg);
2754 dev_err(&(client->dev), "failed to add sysfs entries\n");
2756 sii9234_wq = create_singlethread_workqueue("sii9234_wq");
2759 "[ERROR] %s() workqueue create fail\n", __func__);
2763 INIT_WORK(&(sii9234->sii9234_int_work), sii9234_detection_callback);
2765 pr_info("%s(): create mhl sysfile\n", __func__);
2767 sec_mhl = class_create(THIS_MODULE, "mhl");
2768 if (IS_ERR(sec_mhl)) {
2769 pr_err("Failed to create class(sec_mhl)!\n");
2774 ret = class_create_file(sec_mhl, &class_attr_ddc_i2c_num);
2776 pr_err("Failed to create device file in sysfs entries!\n");
2780 #ifdef CONFIG_SS_FACTORY
2781 ret = class_create_file(sec_mhl, &class_attr_test_result);
2783 pr_err("Failed to create device file in sysfs entries!\n");
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);
2794 sii9234->input_dev = input;
2795 input_set_drvdata(input, sii9234);
2796 input->name = "sii9234_rcp";
2797 input->id.bustype = BUS_I2C;
2799 ret = input_register_device(input);
2801 dev_err(&client->dev, "fail to register input device\n");
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__);
2811 ret = request_threaded_irq(client->irq, NULL, sii9234_irq_thread,
2812 IRQF_TRIGGER_RISING | IRQF_ONESHOT,
2813 "sii9234", sii9234);
2815 printk(KERN_ERR "[ERROR] %s() register thread fail\n",
2821 INIT_WORK(&sii9234->msc_work, sii9234_process_msc_work);
2822 disable_irq(client->irq);
2827 #ifdef CONFIG_SII9234_RCP
2828 input_unregister_device(input);
2832 #ifdef CONFIG_SS_FACTORY
2833 class_remove_file(sec_mhl, &class_attr_test_result);
2837 class_remove_file(sec_mhl, &class_attr_ddc_i2c_num);
2840 class_destroy(sec_mhl);
2843 destroy_workqueue(sii9234_wq);
2846 device_remove_file(&(client->dev), &dev_attr_mhl_read_reg);
2848 mutex_destroy(&sii9234->lock);
2849 mutex_destroy(&sii9234->msc_lock);
2852 #ifdef CONFIG_SII9234_RCP
2853 input_free_device(input);
2861 static int __devinit sii9234_tpi_i2c_probe(struct i2c_client *client,
2862 const struct i2c_device_id *id)
2864 struct sii9234_platform_data *pdata = client->dev.platform_data;
2866 printk(KERN_ERR "[ERROR] %s() fail\n", __func__);
2869 pdata->tpi_client = client;
2873 static int __devinit sii9234_hdmi_rx_i2c_probe(struct i2c_client *client,
2874 const struct i2c_device_id *id)
2876 struct sii9234_platform_data *pdata = client->dev.platform_data;
2878 printk(KERN_ERR "[ERROR] %s() fail\n", __func__);
2882 pdata->hdmi_rx_client = client;
2886 static int __devinit sii9234_cbus_i2c_probe(struct i2c_client *client,
2887 const struct i2c_device_id *id)
2889 struct sii9234_platform_data *pdata = client->dev.platform_data;
2891 printk(KERN_ERR "[ERROR] %s() fail\n", __func__);
2894 pdata->cbus_client = client;
2898 static int __devexit sii9234_mhl_tx_remove(struct i2c_client *client)
2903 static int __devexit sii9234_tpi_remove(struct i2c_client *client)
2908 static int __devexit sii9234_hdmi_rx_remove(struct i2c_client *client)
2913 static int __devexit sii9234_cbus_remove(struct i2c_client *client)
2918 static const struct i2c_device_id sii9234_mhl_tx_id[] = {
2919 {"sii9234_mhl_tx", 0},
2923 static const struct i2c_device_id sii9234_tpi_id[] = {
2928 static const struct i2c_device_id sii9234_hdmi_rx_id[] = {
2929 {"sii9234_hdmi_rx", 0},
2933 static const struct i2c_device_id sii9234_cbus_id[] = {
2934 {"sii9234_cbus", 0},
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);
2943 static struct i2c_driver sii9234_mhl_tx_i2c_driver = {
2945 .owner = THIS_MODULE,
2946 .name = "sii9234_mhl_tx",
2948 .id_table = sii9234_mhl_tx_id,
2949 .probe = sii9234_mhl_tx_i2c_probe,
2950 .remove = __devexit_p(sii9234_mhl_tx_remove),
2954 static struct i2c_driver sii9234_tpi_i2c_driver = {
2956 .owner = THIS_MODULE,
2957 .name = "sii9234_tpi",
2959 .id_table = sii9234_tpi_id,
2960 .probe = sii9234_tpi_i2c_probe,
2961 .remove = __devexit_p(sii9234_tpi_remove),
2964 static struct i2c_driver sii9234_hdmi_rx_i2c_driver = {
2966 .owner = THIS_MODULE,
2967 .name = "sii9234_hdmi_rx",
2969 .id_table = sii9234_hdmi_rx_id,
2970 .probe = sii9234_hdmi_rx_i2c_probe,
2971 .remove = __devexit_p(sii9234_hdmi_rx_remove),
2974 static struct i2c_driver sii9234_cbus_i2c_driver = {
2976 .owner = THIS_MODULE,
2977 .name = "sii9234_cbus",
2979 .id_table = sii9234_cbus_id,
2980 .probe = sii9234_cbus_i2c_probe,
2981 .remove = __devexit_p(sii9234_cbus_remove),
2984 static int __init sii9234_init(void)
2988 ret = i2c_add_driver(&sii9234_mhl_tx_i2c_driver);
2990 printk(KERN_ERR "[ERROR] %s():%d failed !\n", __func__,
2995 ret = i2c_add_driver(&sii9234_tpi_i2c_driver);
2999 ret = i2c_add_driver(&sii9234_hdmi_rx_i2c_driver);
3003 ret = i2c_add_driver(&sii9234_cbus_i2c_driver);
3010 i2c_del_driver(&sii9234_hdmi_rx_i2c_driver);
3012 i2c_del_driver(&sii9234_tpi_i2c_driver);
3014 i2c_del_driver(&sii9234_mhl_tx_i2c_driver);
3015 pr_err("i2c_add_driver fail\n");
3019 static void __exit sii9234_exit(void)
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);
3027 module_init(sii9234_init);
3028 module_exit(sii9234_exit);