mhl_8334.c 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721
  1. /* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. */
  13. #include <linux/types.h>
  14. #include <linux/bitops.h>
  15. #include <linux/clk.h>
  16. #include <linux/mutex.h>
  17. #include <mach/msm_hdmi_audio.h>
  18. #include <mach/clk.h>
  19. #include <mach/msm_iomap.h>
  20. #include <mach/socinfo.h>
  21. #include <linux/gpio.h>
  22. #include <linux/delay.h>
  23. #include <linux/slab.h>
  24. #include <linux/i2c.h>
  25. #include <linux/module.h>
  26. #include <linux/kernel.h>
  27. #include <linux/init.h>
  28. #include <linux/fs.h>
  29. #include <linux/regulator/consumer.h>
  30. #include <linux/device.h>
  31. #include <linux/platform_device.h>
  32. #include <linux/mhl_8334.h>
  33. #include "msm_fb.h"
  34. #include "external_common.h"
  35. #include "hdmi_msm.h"
  36. #include "mhl_i2c_utils.h"
  37. #define MSC_START_BIT_MSC_CMD (0x01 << 0)
  38. #define MSC_START_BIT_VS_CMD (0x01 << 1)
  39. #define MSC_START_BIT_READ_REG (0x01 << 2)
  40. #define MSC_START_BIT_WRITE_REG (0x01 << 3)
  41. #define MSC_START_BIT_WRITE_BURST (0x01 << 4)
  42. static struct i2c_device_id mhl_sii_i2c_id[] = {
  43. { MHL_DRIVER_NAME, 0 },
  44. { }
  45. };
  46. struct mhl_msm_state_t *mhl_msm_state;
  47. spinlock_t mhl_state_lock;
  48. struct workqueue_struct *msc_send_workqueue;
  49. static int mhl_i2c_probe(struct i2c_client *client,\
  50. const struct i2c_device_id *id);
  51. static int mhl_i2c_remove(struct i2c_client *client);
  52. static void force_usb_switch_open(void);
  53. static void release_usb_switch_open(void);
  54. static void switch_mode(enum mhl_st_type to_mode);
  55. static irqreturn_t mhl_tx_isr(int irq, void *dev_id);
  56. void (*notify_usb_online)(int online);
  57. static void mhl_drive_hpd(uint8_t to_state);
  58. static int mhl_send_msc_command(struct msc_command_struct *req);
  59. static void list_cmd_put(struct msc_command_struct *cmd);
  60. static struct msc_command_struct *list_cmd_get(void);
  61. static void mhl_msc_send_work(struct work_struct *work);
  62. static struct i2c_driver mhl_sii_i2c_driver = {
  63. .driver = {
  64. .name = MHL_DRIVER_NAME,
  65. .owner = THIS_MODULE,
  66. },
  67. .probe = mhl_i2c_probe,
  68. /*.remove = __exit_p(mhl_i2c_remove),*/
  69. .remove = mhl_i2c_remove,
  70. .id_table = mhl_sii_i2c_id,
  71. };
  72. static void mhl_sii_reset_pin(int on)
  73. {
  74. gpio_set_value(mhl_msm_state->mhl_data->gpio_mhl_reset, on);
  75. return;
  76. }
  77. static int mhl_sii_reg_enable(void)
  78. {
  79. static struct regulator *reg_8038_l20;
  80. static struct regulator *reg_8038_l11;
  81. int rc;
  82. pr_debug("Inside %s\n", __func__);
  83. if (!reg_8038_l20) {
  84. reg_8038_l20 = regulator_get(&mhl_msm_state->i2c_client->dev,
  85. "mhl_avcc12");
  86. if (IS_ERR(reg_8038_l20)) {
  87. pr_err("could not get reg_8038_l20, rc = %ld\n",
  88. PTR_ERR(reg_8038_l20));
  89. return -ENODEV;
  90. }
  91. rc = regulator_enable(reg_8038_l20);
  92. if (rc) {
  93. pr_err("'%s' regulator enable failed, rc=%d\n",
  94. "mhl_l20", rc);
  95. return rc;
  96. } else
  97. pr_debug("REGULATOR L20 ENABLED\n");
  98. }
  99. if (!reg_8038_l11) {
  100. reg_8038_l11 = regulator_get(&mhl_msm_state->i2c_client->dev,
  101. "mhl_iovcc18");
  102. if (IS_ERR(reg_8038_l11)) {
  103. pr_err("could not get reg_8038_l11, rc = %ld\n",
  104. PTR_ERR(reg_8038_l11));
  105. return -ENODEV;
  106. }
  107. rc = regulator_enable(reg_8038_l11);
  108. if (rc) {
  109. pr_err("'%s' regulator enable failed, rc=%d\n",
  110. "mhl_l11", rc);
  111. return rc;
  112. } else
  113. pr_debug("REGULATOR L11 ENABLED\n");
  114. }
  115. return rc;
  116. }
  117. static void mhl_sii_power_on(void)
  118. {
  119. int ret;
  120. pr_debug("MHL SII POWER ON\n");
  121. if (!mhl_msm_state->mhl_data->gpio_mhl_power) {
  122. pr_warn("%s: no power reqd for this platform\n", __func__);
  123. return;
  124. }
  125. ret = gpio_request(mhl_msm_state->mhl_data->gpio_mhl_power, "W_PWR");
  126. if (ret < 0) {
  127. pr_err("MHL_POWER_GPIO req failed: %d\n",
  128. ret);
  129. return;
  130. }
  131. ret = gpio_direction_output(mhl_msm_state->mhl_data->gpio_mhl_power,
  132. 1);
  133. if (ret < 0) {
  134. pr_err(
  135. "SET GPIO MHL_POWER_GPIO direction failed: %d\n",
  136. ret);
  137. gpio_free(mhl_msm_state->mhl_data->gpio_mhl_power);
  138. return;
  139. }
  140. gpio_set_value(mhl_msm_state->mhl_data->gpio_mhl_power, 1);
  141. if (mhl_sii_reg_enable())
  142. pr_err("Regulator enable failed\n");
  143. pr_debug("MHL SII POWER ON Successful\n");
  144. return;
  145. }
  146. /*
  147. * Request for GPIO allocations
  148. * Set appropriate GPIO directions
  149. */
  150. static int mhl_sii_gpio_setup(int on)
  151. {
  152. int ret;
  153. if (on) {
  154. if (mhl_msm_state->mhl_data->gpio_hdmi_mhl_mux) {
  155. ret = gpio_request(mhl_msm_state->\
  156. mhl_data->gpio_hdmi_mhl_mux, "W_MUX");
  157. if (ret < 0) {
  158. pr_err("GPIO HDMI_MHL MUX req failed:%d\n",
  159. ret);
  160. return -EBUSY;
  161. }
  162. ret = gpio_direction_output(
  163. mhl_msm_state->mhl_data->gpio_hdmi_mhl_mux, 0);
  164. if (ret < 0) {
  165. pr_err("SET GPIO HDMI_MHL dir failed:%d\n",
  166. ret);
  167. gpio_free(mhl_msm_state->\
  168. mhl_data->gpio_hdmi_mhl_mux);
  169. return -EBUSY;
  170. }
  171. msleep(50);
  172. gpio_set_value(mhl_msm_state->\
  173. mhl_data->gpio_hdmi_mhl_mux, 0);
  174. pr_debug("SET GPIO HDMI MHL MUX %d to 0\n",
  175. mhl_msm_state->mhl_data->gpio_hdmi_mhl_mux);
  176. }
  177. ret = gpio_request(mhl_msm_state->mhl_data->gpio_mhl_reset,
  178. "W_RST#");
  179. if (ret < 0) {
  180. pr_err("GPIO RESET request failed: %d\n", ret);
  181. return -EBUSY;
  182. }
  183. ret = gpio_direction_output(mhl_msm_state->\
  184. mhl_data->gpio_mhl_reset, 1);
  185. if (ret < 0) {
  186. pr_err("SET GPIO RESET direction failed: %d\n", ret);
  187. gpio_free(mhl_msm_state->mhl_data->gpio_mhl_reset);
  188. gpio_free(mhl_msm_state->mhl_data->gpio_hdmi_mhl_mux);
  189. return -EBUSY;
  190. }
  191. ret = gpio_request(mhl_msm_state->mhl_data->gpio_mhl_int,
  192. "W_INT");
  193. if (ret < 0) {
  194. pr_err("GPIO INT request failed: %d\n", ret);
  195. gpio_free(mhl_msm_state->mhl_data->gpio_mhl_reset);
  196. gpio_free(mhl_msm_state->mhl_data->gpio_hdmi_mhl_mux);
  197. return -EBUSY;
  198. }
  199. ret = gpio_direction_input(mhl_msm_state->\
  200. mhl_data->gpio_mhl_int);
  201. if (ret < 0) {
  202. pr_err("SET GPIO INTR direction failed: %d\n", ret);
  203. gpio_free(mhl_msm_state->mhl_data->gpio_mhl_reset);
  204. gpio_free(mhl_msm_state->mhl_data->gpio_mhl_int);
  205. gpio_free(mhl_msm_state->mhl_data->gpio_hdmi_mhl_mux);
  206. return -EBUSY;
  207. }
  208. } else {
  209. gpio_free(mhl_msm_state->mhl_data->gpio_mhl_reset);
  210. gpio_free(mhl_msm_state->mhl_data->gpio_mhl_int);
  211. gpio_free(mhl_msm_state->mhl_data->gpio_hdmi_mhl_mux);
  212. gpio_free(mhl_msm_state->mhl_data->gpio_mhl_power);
  213. }
  214. return 0;
  215. }
  216. /* USB_HANDSHAKING FUNCTIONS */
  217. int mhl_device_discovery(const char *name, int *result)
  218. {
  219. int timeout ;
  220. mhl_i2c_reg_write(TX_PAGE_3, 0x0010, 0x27);
  221. msleep(50);
  222. if (mhl_msm_state->cur_state == POWER_STATE_D3) {
  223. /* give MHL driver chance to handle RGND interrupt */
  224. INIT_COMPLETION(mhl_msm_state->rgnd_done);
  225. timeout = wait_for_completion_interruptible_timeout
  226. (&mhl_msm_state->rgnd_done, HZ/2);
  227. if (!timeout) {
  228. /* most likely nothing plugged in USB */
  229. /* USB HOST connected or already in USB mode */
  230. pr_debug("Timedout Returning from discovery mode\n");
  231. *result = MHL_DISCOVERY_RESULT_USB;
  232. return 0;
  233. }
  234. *result = mhl_msm_state->mhl_mode ?
  235. MHL_DISCOVERY_RESULT_MHL : MHL_DISCOVERY_RESULT_USB;
  236. } else
  237. /* not in D3. already in MHL mode */
  238. *result = MHL_DISCOVERY_RESULT_MHL;
  239. return 0;
  240. }
  241. EXPORT_SYMBOL(mhl_device_discovery);
  242. int mhl_register_callback(const char *name, void (*callback)(int online))
  243. {
  244. pr_debug("%s\n", __func__);
  245. if (!callback)
  246. return -EINVAL;
  247. if (!notify_usb_online)
  248. notify_usb_online = callback;
  249. return 0;
  250. }
  251. EXPORT_SYMBOL(mhl_register_callback);
  252. int mhl_unregister_callback(const char *name)
  253. {
  254. pr_debug("%s\n", __func__);
  255. if (notify_usb_online)
  256. notify_usb_online = NULL;
  257. return 0;
  258. }
  259. EXPORT_SYMBOL(mhl_unregister_callback);
  260. static void cbus_reset(void)
  261. {
  262. uint8_t i;
  263. /*
  264. * REG_SRST
  265. */
  266. mhl_i2c_reg_modify(TX_PAGE_3, 0x0000, BIT3, BIT3);
  267. msleep(20);
  268. mhl_i2c_reg_modify(TX_PAGE_3, 0x0000, BIT3, 0x00);
  269. /*
  270. * REG_INTR1 and REG_INTR4
  271. */
  272. mhl_i2c_reg_write(TX_PAGE_L0, 0x0075, BIT6);
  273. mhl_i2c_reg_write(TX_PAGE_3, 0x0022,
  274. BIT0 | BIT2 | BIT3 | BIT4 | BIT5 | BIT6);
  275. /* REG5 */
  276. if (mhl_msm_state->chip_rev_id < 1)
  277. mhl_i2c_reg_write(TX_PAGE_3, 0x0024, BIT3 | BIT4);
  278. else
  279. /*REG5 Mask disabled due to auto FIFO reset ??*/
  280. mhl_i2c_reg_write(TX_PAGE_3, 0x0024, 0x00);
  281. /* Unmask CBUS1 Intrs */
  282. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x0009,
  283. BIT2 | BIT3 | BIT4 | BIT5 | BIT6);
  284. /* Unmask CBUS2 Intrs */
  285. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x001F, BIT2 | BIT3);
  286. for (i = 0; i < 4; i++) {
  287. /*
  288. * Enable WRITE_STAT interrupt for writes to
  289. * all 4 MSC Status registers.
  290. */
  291. mhl_i2c_reg_write(TX_PAGE_CBUS, (0xE0 + i), 0xFF);
  292. /*
  293. * Enable SET_INT interrupt for writes to
  294. * all 4 MSC Interrupt registers.
  295. */
  296. mhl_i2c_reg_write(TX_PAGE_CBUS, (0xF0 + i), 0xFF);
  297. }
  298. }
  299. static void init_cbus_regs(void)
  300. {
  301. uint8_t regval;
  302. /* Increase DDC translation layer timer*/
  303. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x0007, 0xF2);
  304. /* Drive High Time */
  305. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x0036, 0x03);
  306. /* Use programmed timing */
  307. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x0039, 0x30);
  308. /* CBUS Drive Strength */
  309. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x0040, 0x03);
  310. /*
  311. * Write initial default settings
  312. * to devcap regs: default settings
  313. */
  314. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x0080 | DEVCAP_OFFSET_DEV_STATE,
  315. DEVCAP_VAL_DEV_STATE);
  316. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x0080 | DEVCAP_OFFSET_MHL_VERSION,
  317. DEVCAP_VAL_MHL_VERSION);
  318. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x0080 | DEVCAP_OFFSET_DEV_CAT,
  319. DEVCAP_VAL_DEV_CAT);
  320. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x0080 | DEVCAP_OFFSET_ADOPTER_ID_H,
  321. DEVCAP_VAL_ADOPTER_ID_H);
  322. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x0080 | DEVCAP_OFFSET_ADOPTER_ID_L,
  323. DEVCAP_VAL_ADOPTER_ID_L);
  324. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x0080 | DEVCAP_OFFSET_VID_LINK_MODE,
  325. DEVCAP_VAL_VID_LINK_MODE);
  326. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x0080 | DEVCAP_OFFSET_AUD_LINK_MODE,
  327. DEVCAP_VAL_AUD_LINK_MODE);
  328. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x0080 | DEVCAP_OFFSET_VIDEO_TYPE,
  329. DEVCAP_VAL_VIDEO_TYPE);
  330. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x0080 | DEVCAP_OFFSET_LOG_DEV_MAP,
  331. DEVCAP_VAL_LOG_DEV_MAP);
  332. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x0080 | DEVCAP_OFFSET_BANDWIDTH,
  333. DEVCAP_VAL_BANDWIDTH);
  334. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x0080 | DEVCAP_OFFSET_FEATURE_FLAG,
  335. DEVCAP_VAL_FEATURE_FLAG);
  336. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x0080 | DEVCAP_OFFSET_DEVICE_ID_H,
  337. DEVCAP_VAL_DEVICE_ID_H);
  338. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x0080 | DEVCAP_OFFSET_DEVICE_ID_L,
  339. DEVCAP_VAL_DEVICE_ID_L);
  340. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x0080 | DEVCAP_OFFSET_SCRATCHPAD_SIZE,
  341. DEVCAP_VAL_SCRATCHPAD_SIZE);
  342. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x0080 | DEVCAP_OFFSET_INT_STAT_SIZE,
  343. DEVCAP_VAL_INT_STAT_SIZE);
  344. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x0080 | DEVCAP_OFFSET_RESERVED,
  345. DEVCAP_VAL_RESERVED);
  346. /* Make bits 2,3 (initiator timeout) to 1,1
  347. * for register CBUS_LINK_CONTROL_2
  348. * REG_CBUS_LINK_CONTROL_2
  349. */
  350. regval = mhl_i2c_reg_read(TX_PAGE_CBUS, 0x0031);
  351. regval = (regval | 0x0C);
  352. /* REG_CBUS_LINK_CONTROL_2 */
  353. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x0031, regval);
  354. /* REG_MSC_TIMEOUT_LIMIT */
  355. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x0022, 0x0F);
  356. /* REG_CBUS_LINK_CONTROL_1 */
  357. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x0030, 0x01);
  358. /* disallow vendor specific commands */
  359. mhl_i2c_reg_modify(TX_PAGE_CBUS, 0x002E, BIT4, BIT4);
  360. }
  361. /*
  362. * Configure the initial reg settings
  363. */
  364. static void mhl_init_reg_settings(bool mhl_disc_en)
  365. {
  366. /*
  367. * ============================================
  368. * POWER UP
  369. * ============================================
  370. */
  371. /* Power up 1.2V core */
  372. mhl_i2c_reg_write(TX_PAGE_L1, 0x003D, 0x3F);
  373. /*
  374. * Wait for the source power to be enabled
  375. * before enabling pll clocks.
  376. */
  377. msleep(50);
  378. /* Enable Tx PLL Clock */
  379. mhl_i2c_reg_write(TX_PAGE_2, 0x0011, 0x01);
  380. /* Enable Tx Clock Path and Equalizer */
  381. mhl_i2c_reg_write(TX_PAGE_2, 0x0012, 0x11);
  382. /* Tx Source Termination ON */
  383. mhl_i2c_reg_write(TX_PAGE_3, 0x0030, 0x10);
  384. /* Enable 1X MHL Clock output */
  385. mhl_i2c_reg_write(TX_PAGE_3, 0x0035, 0xAC);
  386. /* Tx Differential Driver Config */
  387. mhl_i2c_reg_write(TX_PAGE_3, 0x0031, 0x3C);
  388. mhl_i2c_reg_write(TX_PAGE_3, 0x0033, 0xD9);
  389. /* PLL Bandwidth Control */
  390. mhl_i2c_reg_write(TX_PAGE_3, 0x0037, 0x02);
  391. /*
  392. * ============================================
  393. * Analog PLL Control
  394. * ============================================
  395. */
  396. /* Enable Rx PLL clock */
  397. mhl_i2c_reg_write(TX_PAGE_L0, 0x0080, 0x00);
  398. mhl_i2c_reg_write(TX_PAGE_L0, 0x00F8, 0x0C);
  399. mhl_i2c_reg_write(TX_PAGE_L0, 0x0085, 0x02);
  400. mhl_i2c_reg_write(TX_PAGE_2, 0x0000, 0x00);
  401. mhl_i2c_reg_write(TX_PAGE_2, 0x0013, 0x60);
  402. /* PLL Cal ref sel */
  403. mhl_i2c_reg_write(TX_PAGE_2, 0x0017, 0x03);
  404. /* VCO Cal */
  405. mhl_i2c_reg_write(TX_PAGE_2, 0x001A, 0x20);
  406. /* Auto EQ */
  407. mhl_i2c_reg_write(TX_PAGE_2, 0x0022, 0xE0);
  408. mhl_i2c_reg_write(TX_PAGE_2, 0x0023, 0xC0);
  409. mhl_i2c_reg_write(TX_PAGE_2, 0x0024, 0xA0);
  410. mhl_i2c_reg_write(TX_PAGE_2, 0x0025, 0x80);
  411. mhl_i2c_reg_write(TX_PAGE_2, 0x0026, 0x60);
  412. mhl_i2c_reg_write(TX_PAGE_2, 0x0027, 0x40);
  413. mhl_i2c_reg_write(TX_PAGE_2, 0x0028, 0x20);
  414. mhl_i2c_reg_write(TX_PAGE_2, 0x0029, 0x00);
  415. /* Rx PLL Bandwidth 4MHz */
  416. mhl_i2c_reg_write(TX_PAGE_2, 0x0031, 0x0A);
  417. /* Rx PLL Bandwidth value from I2C */
  418. mhl_i2c_reg_write(TX_PAGE_2, 0x0045, 0x06);
  419. mhl_i2c_reg_write(TX_PAGE_2, 0x004B, 0x06);
  420. /* Manual zone control */
  421. mhl_i2c_reg_write(TX_PAGE_2, 0x004C, 0xE0);
  422. /* PLL Mode value */
  423. mhl_i2c_reg_write(TX_PAGE_2, 0x004D, 0x00);
  424. mhl_i2c_reg_write(TX_PAGE_L0, 0x0008, 0x35);
  425. /*
  426. * Discovery Control and Status regs
  427. * Setting De-glitch time to 50 ms (default)
  428. * Switch Control Disabled
  429. */
  430. mhl_i2c_reg_write(TX_PAGE_3, 0x0011, 0xAD);
  431. /* 1.8V CBUS VTH */
  432. mhl_i2c_reg_write(TX_PAGE_3, 0x0014, 0x55);
  433. /* RGND and single Discovery attempt */
  434. mhl_i2c_reg_write(TX_PAGE_3, 0x0015, 0x11);
  435. /* Ignore VBUS */
  436. mhl_i2c_reg_write(TX_PAGE_3, 0x0017, 0x82);
  437. mhl_i2c_reg_write(TX_PAGE_3, 0x0018, 0x24);
  438. /* Pull-up resistance off for IDLE state */
  439. mhl_i2c_reg_write(TX_PAGE_3, 0x0013, 0x8C);
  440. /* Enable CBUS Discovery */
  441. if (mhl_disc_en)
  442. /* Enable MHL Discovery */
  443. mhl_i2c_reg_write(TX_PAGE_3, 0x0010, 0x27);
  444. else
  445. /* Disable MHL Discovery */
  446. mhl_i2c_reg_write(TX_PAGE_3, 0x0010, 0x26);
  447. mhl_i2c_reg_write(TX_PAGE_3, 0x0016, 0x20);
  448. /* MHL CBUS Discovery - immediate comm. */
  449. mhl_i2c_reg_write(TX_PAGE_3, 0x0012, 0x86);
  450. /* Do not force HPD to 0 during wake-up from D3 */
  451. if (mhl_msm_state->cur_state != POWER_STATE_D0_MHL)
  452. mhl_drive_hpd(HPD_DOWN);
  453. /* Enable Auto Soft RESET */
  454. mhl_i2c_reg_write(TX_PAGE_3, 0x0000, 0x084);
  455. /* HDMI Transcode mode enable */
  456. mhl_i2c_reg_write(TX_PAGE_L0, 0x000D, 0x1C);
  457. cbus_reset();
  458. init_cbus_regs();
  459. }
  460. static int mhl_chip_init(void)
  461. {
  462. /* Read the chip rev ID */
  463. mhl_msm_state->chip_rev_id = mhl_i2c_reg_read(TX_PAGE_L0, 0x04);
  464. pr_debug("MHL: chip rev ID read=[%x]\n", mhl_msm_state->chip_rev_id);
  465. /* Reset the TX chip */
  466. mhl_sii_reset_pin(1);
  467. msleep(20);
  468. mhl_sii_reset_pin(0);
  469. msleep(20);
  470. mhl_sii_reset_pin(1);
  471. /* MHL spec requires a 100 ms wait here. */
  472. msleep(100);
  473. /*
  474. * Need to disable MHL discovery
  475. */
  476. mhl_init_reg_settings(true);
  477. /*
  478. * Power down the chip to the
  479. * D3 - a low power standby mode
  480. * cable impedance measurement logic is operational
  481. */
  482. switch_mode(POWER_STATE_D3);
  483. return 0;
  484. }
  485. /*
  486. * I2C probe
  487. */
  488. static int mhl_i2c_probe(struct i2c_client *client,
  489. const struct i2c_device_id *id)
  490. {
  491. int ret;
  492. struct msm_mhl_platform_data *tmp = client->dev.platform_data;
  493. if (!tmp->mhl_enabled) {
  494. ret = -ENODEV;
  495. pr_warn("MHL feautre left disabled\n");
  496. goto probe_early_exit;
  497. }
  498. mhl_msm_state->mhl_data = kzalloc(sizeof(struct msm_mhl_platform_data),
  499. GFP_KERNEL);
  500. if (!(mhl_msm_state->mhl_data)) {
  501. ret = -ENOMEM;
  502. pr_err("MHL I2C Probe failed - no mem\n");
  503. goto probe_early_exit;
  504. }
  505. mhl_msm_state->i2c_client = client;
  506. spin_lock_init(&mhl_state_lock);
  507. i2c_set_clientdata(client, mhl_msm_state);
  508. mhl_msm_state->mhl_data = client->dev.platform_data;
  509. pr_debug("MHL: mhl_msm_state->mhl_data->irq=[%d]\n",
  510. mhl_msm_state->mhl_data->irq);
  511. msc_send_workqueue = create_workqueue("mhl_msc_cmd_queue");
  512. mhl_msm_state->cur_state = POWER_STATE_D0_MHL;
  513. /* Init GPIO stuff here */
  514. ret = mhl_sii_gpio_setup(1);
  515. if (ret) {
  516. pr_err("MHL: mhl_gpio_init has failed\n");
  517. ret = -ENODEV;
  518. goto probe_early_exit;
  519. }
  520. mhl_sii_power_on();
  521. /* MHL SII 8334 chip specific init */
  522. mhl_chip_init();
  523. init_completion(&mhl_msm_state->rgnd_done);
  524. /* Request IRQ stuff here */
  525. pr_debug("MHL: mhl_msm_state->mhl_data->irq=[%d]\n",
  526. mhl_msm_state->mhl_data->irq);
  527. ret = request_threaded_irq(mhl_msm_state->mhl_data->irq, NULL,
  528. &mhl_tx_isr,
  529. IRQF_TRIGGER_LOW | IRQF_ONESHOT,
  530. "mhl_tx_isr", mhl_msm_state);
  531. if (ret) {
  532. pr_err("request_threaded_irq failed, status: %d\n",
  533. ret);
  534. goto probe_exit;
  535. } else {
  536. pr_debug("request_threaded_irq succeeded\n");
  537. }
  538. INIT_WORK(&mhl_msm_state->mhl_msc_send_work, mhl_msc_send_work);
  539. INIT_LIST_HEAD(&mhl_msm_state->list_cmd);
  540. mhl_msm_state->msc_command_put_work = list_cmd_put;
  541. mhl_msm_state->msc_command_get_work = list_cmd_get;
  542. init_completion(&mhl_msm_state->msc_cmd_done);
  543. pr_debug("i2c probe successful\n");
  544. return 0;
  545. probe_exit:
  546. if (mhl_msm_state->mhl_data) {
  547. /* free the gpios */
  548. mhl_sii_gpio_setup(0);
  549. kfree(mhl_msm_state->mhl_data);
  550. mhl_msm_state->mhl_data = NULL;
  551. }
  552. probe_early_exit:
  553. return ret;
  554. }
  555. static int mhl_i2c_remove(struct i2c_client *client)
  556. {
  557. pr_debug("%s\n", __func__);
  558. mhl_sii_gpio_setup(0);
  559. kfree(mhl_msm_state->mhl_data);
  560. return 0;
  561. }
  562. static void list_cmd_put(struct msc_command_struct *cmd)
  563. {
  564. struct msc_cmd_envelope *new_cmd;
  565. new_cmd = vmalloc(sizeof(struct msc_cmd_envelope));
  566. memcpy(&new_cmd->msc_cmd_msg, cmd,
  567. sizeof(struct msc_command_struct));
  568. /* Need to check for queue getting filled up */
  569. list_add_tail(&new_cmd->msc_queue_envelope, &mhl_msm_state->list_cmd);
  570. }
  571. static struct msc_command_struct *list_cmd_get(void)
  572. {
  573. struct msc_cmd_envelope *cmd_env =
  574. list_first_entry(&mhl_msm_state->list_cmd,
  575. struct msc_cmd_envelope, msc_queue_envelope);
  576. list_del(&cmd_env->msc_queue_envelope);
  577. return &cmd_env->msc_cmd_msg;
  578. }
  579. static void mhl_msc_send_work(struct work_struct *work)
  580. {
  581. int ret;
  582. /*
  583. * Remove item from the queue
  584. * and schedule it
  585. */
  586. struct msc_command_struct *req;
  587. while (!list_empty(&mhl_msm_state->list_cmd)) {
  588. req = mhl_msm_state->msc_command_get_work();
  589. ret = mhl_send_msc_command(req);
  590. if (ret == -EAGAIN)
  591. pr_err("MHL: Queue still busy!!\n");
  592. else {
  593. vfree(req);
  594. pr_debug("MESSAGE SENT!!!!\n");
  595. }
  596. }
  597. }
  598. static int __init mhl_msm_init(void)
  599. {
  600. int32_t ret;
  601. pr_debug("%s\n", __func__);
  602. mhl_msm_state = kzalloc(sizeof(struct mhl_msm_state_t), GFP_KERNEL);
  603. if (!mhl_msm_state) {
  604. pr_err("mhl_msm_init FAILED: out of memory\n");
  605. ret = -ENOMEM;
  606. goto init_exit;
  607. }
  608. mhl_msm_state->i2c_client = NULL;
  609. ret = i2c_add_driver(&mhl_sii_i2c_driver);
  610. if (ret) {
  611. pr_err("MHL: I2C driver add failed: %d\n", ret);
  612. ret = -ENODEV;
  613. goto init_exit;
  614. } else {
  615. if (mhl_msm_state->i2c_client == NULL) {
  616. i2c_del_driver(&mhl_sii_i2c_driver);
  617. pr_err("MHL: I2C driver add failed\n");
  618. ret = -ENODEV;
  619. goto init_exit;
  620. }
  621. pr_info("MHL: I2C driver added\n");
  622. }
  623. return 0;
  624. init_exit:
  625. pr_err("Exiting from the init with err\n");
  626. if (!mhl_msm_state) {
  627. kfree(mhl_msm_state);
  628. mhl_msm_state = NULL;
  629. }
  630. return ret;
  631. }
  632. static void mhl_msc_sched_work(struct msc_command_struct *req)
  633. {
  634. /*
  635. * Put an item to the queue
  636. * and schedule work
  637. */
  638. mhl_msm_state->msc_command_put_work(req);
  639. queue_work(msc_send_workqueue, &mhl_msm_state->mhl_msc_send_work);
  640. }
  641. static void switch_mode(enum mhl_st_type to_mode)
  642. {
  643. unsigned long flags;
  644. switch (to_mode) {
  645. case POWER_STATE_D0_NO_MHL:
  646. break;
  647. case POWER_STATE_D0_MHL:
  648. mhl_init_reg_settings(true);
  649. /* REG_DISC_CTRL1 */
  650. mhl_i2c_reg_modify(TX_PAGE_3, 0x0010, BIT1 | BIT0, BIT0);
  651. /*
  652. * TPI_DEVICE_POWER_STATE_CTRL_REG
  653. * TX_POWER_STATE_MASK = BIT1 | BIT0
  654. */
  655. mhl_i2c_reg_modify(TX_PAGE_TPI, 0x001E, BIT1 | BIT0, 0x00);
  656. break;
  657. case POWER_STATE_D3:
  658. if (mhl_msm_state->cur_state != POWER_STATE_D3) {
  659. /* Force HPD to 0 when not in MHL mode. */
  660. mhl_drive_hpd(HPD_DOWN);
  661. /*
  662. * Change TMDS termination to high impedance
  663. * on disconnection.
  664. */
  665. mhl_i2c_reg_write(TX_PAGE_3, 0x0030, 0xD0);
  666. msleep(50);
  667. mhl_i2c_reg_modify(TX_PAGE_3, 0x0010,
  668. BIT1 | BIT0, 0x00);
  669. mhl_i2c_reg_modify(TX_PAGE_3, 0x003D, BIT0, 0x00);
  670. spin_lock_irqsave(&mhl_state_lock, flags);
  671. mhl_msm_state->cur_state = POWER_STATE_D3;
  672. spin_unlock_irqrestore(&mhl_state_lock, flags);
  673. }
  674. break;
  675. default:
  676. break;
  677. }
  678. }
  679. static void mhl_drive_hpd(uint8_t to_state)
  680. {
  681. if (mhl_msm_state->cur_state != POWER_STATE_D0_MHL) {
  682. pr_err("MHL: invalid state to ctrl HPD\n");
  683. return;
  684. }
  685. pr_debug("%s: To state=[0x%x]\n", __func__, to_state);
  686. if (to_state == HPD_UP) {
  687. /*
  688. * Drive HPD to UP state
  689. *
  690. * The below two reg configs combined
  691. * enable TMDS output.
  692. */
  693. /* Enable TMDS on TMDS_CCTRL */
  694. mhl_i2c_reg_modify(TX_PAGE_L0, 0x0080, BIT4, BIT4);
  695. /*
  696. * Set HPD_OUT_OVR_EN = HPD State
  697. * EDID read and Un-force HPD (from low)
  698. * propogate to src let HPD float by clearing
  699. * HPD OUT OVRRD EN
  700. */
  701. mhl_i2c_reg_modify(TX_PAGE_3, 0x0020, BIT4, 0x00);
  702. } else {
  703. /*
  704. * Drive HPD to DOWN state
  705. * Disable TMDS Output on REG_TMDS_CCTRL
  706. * Enable/Disable TMDS output (MHL TMDS output only)
  707. */
  708. mhl_i2c_reg_modify(TX_PAGE_3, 0x20, BIT4 | BIT5, BIT4);
  709. mhl_i2c_reg_modify(TX_PAGE_L0, 0x0080, BIT4, 0x00);
  710. }
  711. return;
  712. }
  713. static void mhl_msm_connection(void)
  714. {
  715. uint8_t val;
  716. unsigned long flags;
  717. pr_debug("%s: cur state = [0x%x]\n", __func__,
  718. mhl_msm_state->cur_state);
  719. if (mhl_msm_state->cur_state == POWER_STATE_D0_MHL) {
  720. /* Already in D0 - MHL power state */
  721. return;
  722. }
  723. spin_lock_irqsave(&mhl_state_lock, flags);
  724. mhl_msm_state->cur_state = POWER_STATE_D0_MHL;
  725. spin_unlock_irqrestore(&mhl_state_lock, flags);
  726. mhl_i2c_reg_write(TX_PAGE_3, 0x30, 0x10);
  727. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x07, 0xF2);
  728. /*
  729. * Keep the discovery enabled. Need RGND interrupt
  730. * Possibly chip disables discovery after MHL_EST??
  731. * Need to re-enable here
  732. */
  733. val = mhl_i2c_reg_read(TX_PAGE_3, 0x10);
  734. mhl_i2c_reg_write(TX_PAGE_3, 0x10, val | BIT0);
  735. return;
  736. }
  737. static void mhl_msm_disconnection(void)
  738. {
  739. /*
  740. * MHL TX CTL1
  741. * Disabling Tx termination
  742. */
  743. mhl_i2c_reg_write(TX_PAGE_3, 0x30, 0xD0);
  744. /* Change HPD line to drive it low */
  745. mhl_drive_hpd(HPD_DOWN);
  746. /* switch power state to D3 */
  747. switch_mode(POWER_STATE_D3);
  748. return;
  749. }
  750. /*
  751. * If hardware detected a change in impedance and raised an INTR
  752. * We check the range of this impedance to infer if the connected
  753. * device is MHL or USB and take appropriate actions.
  754. */
  755. static int mhl_msm_read_rgnd_int(void)
  756. {
  757. uint8_t rgnd_imp;
  758. /*
  759. * DISC STATUS REG 2
  760. * 1:0 RGND
  761. * 00 - open (USB)
  762. * 01 - 2 kOHM (USB)
  763. * 10 - 1 kOHM ***(MHL)**** It's range 800 - 1200 OHM from MHL spec
  764. * 11 - short (USB)
  765. */
  766. rgnd_imp = (mhl_i2c_reg_read(TX_PAGE_3, 0x001C) & (BIT1 | BIT0));
  767. pr_debug("Imp Range read = %02X\n", (int)rgnd_imp);
  768. if (0x02 == rgnd_imp) {
  769. pr_debug("MHL: MHL DEVICE!!!\n");
  770. mhl_i2c_reg_modify(TX_PAGE_3, 0x0018, BIT0, BIT0);
  771. mhl_msm_state->mhl_mode = TRUE;
  772. if (notify_usb_online)
  773. notify_usb_online(1);
  774. } else {
  775. pr_debug("MHL: NON-MHL DEVICE!!!\n");
  776. mhl_msm_state->mhl_mode = FALSE;
  777. mhl_i2c_reg_modify(TX_PAGE_3, 0x0018, BIT3, BIT3);
  778. switch_mode(POWER_STATE_D3);
  779. }
  780. complete(&mhl_msm_state->rgnd_done);
  781. return mhl_msm_state->mhl_mode ?
  782. MHL_DISCOVERY_RESULT_MHL : MHL_DISCOVERY_RESULT_USB;
  783. }
  784. static void force_usb_switch_open(void)
  785. {
  786. /*DISABLE_DISCOVERY*/
  787. mhl_i2c_reg_modify(TX_PAGE_3, 0x0010, BIT0, 0);
  788. /* Force USB ID switch to open*/
  789. mhl_i2c_reg_modify(TX_PAGE_3, 0x0015, BIT6, BIT6);
  790. mhl_i2c_reg_write(TX_PAGE_3, 0x0012, 0x86);
  791. /* Force HPD to 0 when not in Mobile HD mode. */
  792. mhl_i2c_reg_modify(TX_PAGE_3, 0x0020, BIT5 | BIT4, BIT4);
  793. }
  794. static void release_usb_switch_open(void)
  795. {
  796. msleep(50);
  797. mhl_i2c_reg_modify(TX_PAGE_3, 0x0015, BIT6, 0x00);
  798. mhl_i2c_reg_modify(TX_PAGE_3, 0x0010, BIT0, BIT0);
  799. }
  800. static void int_4_isr(void)
  801. {
  802. uint8_t status, reg ;
  803. /* INTR_STATUS4 */
  804. status = mhl_i2c_reg_read(TX_PAGE_3, 0x0021);
  805. /*
  806. * When I2C is inoperational (D3) and
  807. * a previous interrupt brought us here,
  808. * do nothing.
  809. */
  810. if ((0x00 == status) && (mhl_msm_state->cur_state == POWER_STATE_D3)) {
  811. pr_debug("MHL: spurious interrupt\n");
  812. return;
  813. }
  814. if (0xFF != status) {
  815. if ((status & BIT0) && (mhl_msm_state->chip_rev_id < 1)) {
  816. uint8_t tmds_cstat;
  817. uint8_t mhl_fifo_status;
  818. /* TMDS CSTAT */
  819. tmds_cstat = mhl_i2c_reg_read(TX_PAGE_3, 0x0040);
  820. pr_debug("TMDS CSTAT: 0x%02x\n", tmds_cstat);
  821. if (tmds_cstat & 0x02) {
  822. mhl_fifo_status = mhl_i2c_reg_read(TX_PAGE_3,
  823. 0x0023);
  824. pr_debug("MHL FIFO status: 0x%02x\n",
  825. mhl_fifo_status);
  826. if (mhl_fifo_status & 0x0C) {
  827. mhl_i2c_reg_write(TX_PAGE_3, 0x0023,
  828. 0x0C);
  829. pr_debug("Apply MHL FIFO Reset\n");
  830. mhl_i2c_reg_write(TX_PAGE_3, 0x0000,
  831. 0x94);
  832. mhl_i2c_reg_write(TX_PAGE_3, 0x0000,
  833. 0x84);
  834. }
  835. }
  836. }
  837. if (status & BIT1)
  838. pr_debug("MHL: INT4 BIT1 is set\n");
  839. /* MHL_EST interrupt */
  840. if (status & BIT2) {
  841. pr_debug("mhl_msm_connection() from ISR\n");
  842. mhl_connect_api(true);
  843. mhl_msm_connection();
  844. pr_debug("MHL Connect Drv: INT4 Status = %02X\n",
  845. (int) status);
  846. } else if (status & BIT3) {
  847. pr_debug("MHL: uUSB-A type device detected.\n");
  848. mhl_i2c_reg_write(TX_PAGE_3, 0x001C, 0x80);
  849. switch_mode(POWER_STATE_D3);
  850. }
  851. if (status & BIT5) {
  852. mhl_connect_api(false);
  853. /* Clear interrupts - REG INTR4 */
  854. reg = mhl_i2c_reg_read(TX_PAGE_3, 0x0021);
  855. mhl_i2c_reg_write(TX_PAGE_3, 0x0021, reg);
  856. mhl_msm_disconnection();
  857. if (notify_usb_online)
  858. notify_usb_online(0);
  859. pr_debug("MHL Disconnect Drv: INT4 Status = %02X\n",
  860. (int)status);
  861. }
  862. if ((mhl_msm_state->cur_state != POWER_STATE_D0_MHL) &&\
  863. (status & BIT6)) {
  864. /* RGND READY Intr */
  865. switch_mode(POWER_STATE_D0_MHL);
  866. mhl_msm_read_rgnd_int();
  867. }
  868. /* Can't succeed at these in D3 */
  869. if (mhl_msm_state->cur_state != POWER_STATE_D3) {
  870. /* CBUS Lockout interrupt? */
  871. /*
  872. * Hardware detection mechanism figures that
  873. * CBUS line is latched and raises this intr
  874. * where we force usb switch open and release
  875. */
  876. if (status & BIT4) {
  877. force_usb_switch_open();
  878. release_usb_switch_open();
  879. }
  880. }
  881. }
  882. pr_debug("MHL END Drv: INT4 Status = %02X\n", (int) status);
  883. mhl_i2c_reg_write(TX_PAGE_3, 0x0021, status);
  884. return;
  885. }
  886. static void int_5_isr(void)
  887. {
  888. uint8_t intr_5_stat;
  889. /*
  890. * Clear INT 5
  891. * INTR5 is related to FIFO underflow/overflow reset
  892. * which is handled in 8334 by auto FIFO reset
  893. */
  894. intr_5_stat = mhl_i2c_reg_read(TX_PAGE_3, 0x0023);
  895. mhl_i2c_reg_write(TX_PAGE_3, 0x0023, intr_5_stat);
  896. }
  897. static void int_1_isr(void)
  898. {
  899. /* This ISR mainly handles the HPD status changes */
  900. uint8_t intr_1_stat;
  901. uint8_t cbus_stat;
  902. /* INTR STATUS 1 */
  903. intr_1_stat = mhl_i2c_reg_read(TX_PAGE_L0, 0x0071);
  904. if (intr_1_stat) {
  905. /* Clear interrupts */
  906. mhl_i2c_reg_write(TX_PAGE_L0, 0x0071, intr_1_stat);
  907. if (BIT6 & intr_1_stat) {
  908. /*
  909. * HPD status change event is pending
  910. * Read CBUS HPD status for this info
  911. */
  912. /* MSC REQ ABRT REASON */
  913. cbus_stat = mhl_i2c_reg_read(TX_PAGE_CBUS, 0x0D);
  914. if (BIT6 & cbus_stat)
  915. mhl_drive_hpd(HPD_UP);
  916. }
  917. }
  918. return;
  919. }
  920. static void mhl_cbus_process_errors(u8 int_status)
  921. {
  922. u8 abort_reason = 0;
  923. if (int_status & BIT2) {
  924. abort_reason = mhl_i2c_reg_read(TX_PAGE_CBUS, 0x0B);
  925. pr_debug("%s: CBUS DDC Abort Reason(0x%02x)\n",
  926. __func__, abort_reason);
  927. }
  928. if (int_status & BIT5) {
  929. abort_reason = mhl_i2c_reg_read(TX_PAGE_CBUS, 0x0D);
  930. pr_debug("%s: CBUS MSC Requestor Abort Reason(0x%02x)\n",
  931. __func__, abort_reason);
  932. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x0D, 0xFF);
  933. }
  934. if (int_status & BIT6) {
  935. abort_reason = mhl_i2c_reg_read(TX_PAGE_CBUS, 0x0E);
  936. pr_debug("%s: CBUS MSC Responder Abort Reason(0x%02x)\n",
  937. __func__, abort_reason);
  938. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x0E, 0xFF);
  939. }
  940. }
  941. static int mhl_msc_command_done(struct msc_command_struct *req)
  942. {
  943. switch (req->command) {
  944. case MHL_WRITE_STAT:
  945. if (req->offset == MHL_STATUS_REG_LINK_MODE) {
  946. if (req->payload.data[0]
  947. & MHL_STATUS_PATH_ENABLED) {
  948. /* Enable TMDS output */
  949. mhl_i2c_reg_modify(TX_PAGE_L0, 0x0080,
  950. BIT4, BIT4);
  951. } else
  952. /* Disable TMDS output */
  953. mhl_i2c_reg_modify(TX_PAGE_L0, 0x0080,
  954. BIT4, BIT4);
  955. }
  956. break;
  957. case MHL_READ_DEVCAP:
  958. mhl_msm_state->devcap_state |= BIT(req->offset);
  959. switch (req->offset) {
  960. case MHL_DEV_CATEGORY_OFFSET:
  961. if (req->retval & MHL_DEV_CATEGORY_POW_BIT) {
  962. /*
  963. * Enable charging
  964. */
  965. } else {
  966. /*
  967. * Disable charging
  968. */
  969. }
  970. break;
  971. case DEVCAP_OFFSET_MHL_VERSION:
  972. case DEVCAP_OFFSET_INT_STAT_SIZE:
  973. break;
  974. }
  975. break;
  976. }
  977. return 0;
  978. }
  979. static int mhl_send_msc_command(struct msc_command_struct *req)
  980. {
  981. int timeout;
  982. u8 start_bit = 0x00;
  983. u8 *burst_data;
  984. int i;
  985. if (mhl_msm_state->cur_state != POWER_STATE_D0_MHL) {
  986. pr_debug("%s: power_state:%02x CBUS(0x0A):%02x\n",
  987. __func__,
  988. mhl_msm_state->cur_state, mhl_i2c_reg_read(TX_PAGE_CBUS, 0x0A));
  989. return -EFAULT;
  990. }
  991. if (!req)
  992. return -EFAULT;
  993. pr_debug("%s: command=0x%02x offset=0x%02x %02x %02x",
  994. __func__,
  995. req->command,
  996. req->offset,
  997. req->payload.data[0],
  998. req->payload.data[1]);
  999. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x13, req->offset);
  1000. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x14, req->payload.data[0]);
  1001. switch (req->command) {
  1002. case MHL_SET_INT:
  1003. case MHL_WRITE_STAT:
  1004. start_bit = MSC_START_BIT_WRITE_REG;
  1005. break;
  1006. case MHL_READ_DEVCAP:
  1007. start_bit = MSC_START_BIT_READ_REG;
  1008. break;
  1009. case MHL_GET_STATE:
  1010. case MHL_GET_VENDOR_ID:
  1011. case MHL_SET_HPD:
  1012. case MHL_CLR_HPD:
  1013. case MHL_GET_SC1_ERRORCODE:
  1014. case MHL_GET_DDC_ERRORCODE:
  1015. case MHL_GET_MSC_ERRORCODE:
  1016. case MHL_GET_SC3_ERRORCODE:
  1017. start_bit = MSC_START_BIT_MSC_CMD;
  1018. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x13, req->command);
  1019. break;
  1020. case MHL_MSC_MSG:
  1021. start_bit = MSC_START_BIT_VS_CMD;
  1022. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x15, req->payload.data[1]);
  1023. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x13, req->command);
  1024. break;
  1025. case MHL_WRITE_BURST:
  1026. start_bit = MSC_START_BIT_WRITE_BURST;
  1027. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x20, req->length - 1);
  1028. if (!(req->payload.burst_data)) {
  1029. pr_err("%s: burst data is null!\n", __func__);
  1030. goto cbus_send_fail;
  1031. }
  1032. burst_data = req->payload.burst_data;
  1033. for (i = 0; i < req->length; i++, burst_data++)
  1034. mhl_i2c_reg_write(TX_PAGE_CBUS, 0xC0 + i, *burst_data);
  1035. break;
  1036. default:
  1037. pr_err("%s: unknown command! (%02x)\n",
  1038. __func__, req->command);
  1039. goto cbus_send_fail;
  1040. }
  1041. INIT_COMPLETION(mhl_msm_state->msc_cmd_done);
  1042. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x12, start_bit);
  1043. timeout = wait_for_completion_interruptible_timeout
  1044. (&mhl_msm_state->msc_cmd_done, HZ);
  1045. if (!timeout) {
  1046. pr_err("%s: cbus_command_send timed out!\n", __func__);
  1047. goto cbus_send_fail;
  1048. }
  1049. switch (req->command) {
  1050. case MHL_READ_DEVCAP:
  1051. /* devcap */
  1052. req->retval = mhl_i2c_reg_read(TX_PAGE_CBUS, 0x16);
  1053. pr_debug("Read CBUS[0x16]=[%02x]\n", req->retval);
  1054. break;
  1055. case MHL_MSC_MSG:
  1056. /* check if MSC_MSG NACKed */
  1057. if (mhl_i2c_reg_read(TX_PAGE_CBUS, 0x20) & BIT6)
  1058. return -EAGAIN;
  1059. default:
  1060. req->retval = 0;
  1061. break;
  1062. }
  1063. mhl_msc_command_done(req);
  1064. pr_debug("%s: msc cmd done\n", __func__);
  1065. return 0;
  1066. cbus_send_fail:
  1067. return -EFAULT;
  1068. }
  1069. static int mhl_msc_send_set_int(u8 offset, u8 mask)
  1070. {
  1071. struct msc_command_struct req;
  1072. req.command = MHL_SET_INT;
  1073. req.offset = offset;
  1074. req.payload.data[0] = mask;
  1075. mhl_msc_sched_work(&req);
  1076. return 0;
  1077. }
  1078. static int mhl_msc_send_write_stat(u8 offset, u8 value)
  1079. {
  1080. struct msc_command_struct req;
  1081. req.command = MHL_WRITE_STAT;
  1082. req.offset = offset;
  1083. req.payload.data[0] = value;
  1084. mhl_msc_sched_work(&req);
  1085. return 0;
  1086. }
  1087. static int mhl_msc_send_msc_msg(u8 sub_cmd, u8 cmd_data)
  1088. {
  1089. struct msc_command_struct req;
  1090. req.command = MHL_MSC_MSG;
  1091. req.payload.data[0] = sub_cmd;
  1092. req.payload.data[1] = cmd_data;
  1093. mhl_msc_sched_work(&req);
  1094. return 0;
  1095. }
  1096. static int mhl_msc_read_devcap(u8 offset)
  1097. {
  1098. struct msc_command_struct req;
  1099. if (offset < 0 || offset > 15)
  1100. return -EFAULT;
  1101. req.command = MHL_READ_DEVCAP;
  1102. req.offset = offset;
  1103. req.payload.data[0] = 0;
  1104. mhl_msc_sched_work(&req);
  1105. return 0;
  1106. }
  1107. static int mhl_msc_read_devcap_all(void)
  1108. {
  1109. int offset;
  1110. int ret;
  1111. for (offset = 0; offset < DEVCAP_SIZE; offset++) {
  1112. ret = mhl_msc_read_devcap(offset);
  1113. msleep(200);
  1114. if (ret == -EFAULT) {
  1115. pr_err("%s: queue busy!\n", __func__);
  1116. return -EBUSY;
  1117. }
  1118. }
  1119. return 0;
  1120. }
  1121. /* supported RCP key code */
  1122. static const u8 rcp_key_code_tbl[] = {
  1123. 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00~0x07 */
  1124. 0, 0, 0, 0, 0, 0, 0, 0, /* 0x08~0x0f */
  1125. 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10~0x17 */
  1126. 0, 0, 0, 0, 0, 0, 0, 0, /* 0x18~0x1f */
  1127. 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20~0x27 */
  1128. 0, 0, 0, 0, 0, 0, 0, 0, /* 0x28~0x2f */
  1129. 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30~0x37 */
  1130. 0, 0, 0, 0, 0, 0, 0, 0, /* 0x38~0x3f */
  1131. 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40~0x47 */
  1132. 0, 0, 0, 0, 0, 0, 0, 0, /* 0x48~0x4f */
  1133. 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50~0x57 */
  1134. 0, 0, 0, 0, 0, 0, 0, 0, /* 0x58~0x5f */
  1135. 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60~0x67 */
  1136. 0, 0, 0, 0, 0, 0, 0, 0, /* 0x68~0x6f */
  1137. 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70~0x77 */
  1138. 0, 0, 0, 0, 0, 0, 0, 0 /* 0x78~0x7f */
  1139. };
  1140. static int mhl_rcp_recv(u8 key_code)
  1141. {
  1142. int rc;
  1143. if (rcp_key_code_tbl[(key_code & 0x7f)]) {
  1144. /*
  1145. * TODO: Take action for the RCP cmd
  1146. */
  1147. /* send ack to rcp cmd*/
  1148. rc = mhl_msc_send_msc_msg(
  1149. MHL_MSC_MSG_RCPK,
  1150. key_code);
  1151. } else {
  1152. /* send rcp error */
  1153. rc = mhl_msc_send_msc_msg(
  1154. MHL_MSC_MSG_RCPE,
  1155. MHL_RCPE_UNSUPPORTED_KEY_CODE);
  1156. if (rc)
  1157. return rc;
  1158. /* send rcpk after rcpe send */
  1159. rc = mhl_msc_send_msc_msg(
  1160. MHL_MSC_MSG_RCPK,
  1161. key_code);
  1162. }
  1163. return rc;
  1164. }
  1165. static int mhl_rap_action(u8 action_code)
  1166. {
  1167. switch (action_code) {
  1168. case MHL_RAP_CONTENT_ON:
  1169. /*
  1170. * Enable TMDS on TMDS_CCTRL
  1171. */
  1172. mhl_i2c_reg_modify(TX_PAGE_L0, 0x0080, BIT4, BIT4);
  1173. break;
  1174. case MHL_RAP_CONTENT_OFF:
  1175. /*
  1176. * Disable TMDS on TMDS_CCTRL
  1177. */
  1178. mhl_i2c_reg_modify(TX_PAGE_L0, 0x0080, BIT4, 0x00);
  1179. break;
  1180. default:
  1181. break;
  1182. }
  1183. return 0;
  1184. }
  1185. static int mhl_rap_recv(u8 action_code)
  1186. {
  1187. u8 error_code;
  1188. switch (action_code) {
  1189. /*case MHL_RAP_POLL:*/
  1190. case MHL_RAP_CONTENT_ON:
  1191. case MHL_RAP_CONTENT_OFF:
  1192. mhl_rap_action(action_code);
  1193. error_code = MHL_RAPK_NO_ERROR;
  1194. /* notify userspace */
  1195. break;
  1196. default:
  1197. error_code = MHL_RAPK_UNRECOGNIZED_ACTION_CODE;
  1198. break;
  1199. }
  1200. /* prior send rapk */
  1201. return mhl_msc_send_msc_msg(
  1202. MHL_MSC_MSG_RAPK,
  1203. error_code);
  1204. }
  1205. static int mhl_msc_recv_msc_msg(u8 sub_cmd, u8 cmd_data)
  1206. {
  1207. int rc = 0;
  1208. switch (sub_cmd) {
  1209. case MHL_MSC_MSG_RCP:
  1210. pr_debug("MHL: receive RCP(0x%02x)\n", cmd_data);
  1211. rc = mhl_rcp_recv(cmd_data);
  1212. break;
  1213. case MHL_MSC_MSG_RCPK:
  1214. pr_debug("MHL: receive RCPK(0x%02x)\n", cmd_data);
  1215. break;
  1216. case MHL_MSC_MSG_RCPE:
  1217. pr_debug("MHL: receive RCPE(0x%02x)\n", cmd_data);
  1218. break;
  1219. case MHL_MSC_MSG_RAP:
  1220. pr_debug("MHL: receive RAP(0x%02x)\n", cmd_data);
  1221. rc = mhl_rap_recv(cmd_data);
  1222. break;
  1223. case MHL_MSC_MSG_RAPK:
  1224. pr_debug("MHL: receive RAPK(0x%02x)\n", cmd_data);
  1225. break;
  1226. default:
  1227. break;
  1228. }
  1229. return rc;
  1230. }
  1231. static int mhl_msc_recv_set_int(u8 offset, u8 set_int)
  1232. {
  1233. if (offset >= 2)
  1234. return -EFAULT;
  1235. switch (offset) {
  1236. case 0:
  1237. /* DCAP_CHG */
  1238. if (set_int & MHL_INT_DCAP_CHG) {
  1239. /* peer dcap has changed */
  1240. if (mhl_msc_read_devcap_all() == -EBUSY) {
  1241. pr_err("READ DEVCAP FAILED to send successfully\n");
  1242. break;
  1243. }
  1244. }
  1245. /* DSCR_CHG */
  1246. if (set_int & MHL_INT_DSCR_CHG)
  1247. ;
  1248. /* REQ_WRT */
  1249. if (set_int & MHL_INT_REQ_WRT) {
  1250. /* SET_INT: GRT_WRT */
  1251. mhl_msc_send_set_int(
  1252. MHL_RCHANGE_INT,
  1253. MHL_INT_GRT_WRT);
  1254. }
  1255. /* GRT_WRT */
  1256. if (set_int & MHL_INT_GRT_WRT)
  1257. ;
  1258. break;
  1259. case 1:
  1260. /* EDID_CHG */
  1261. if (set_int & MHL_INT_EDID_CHG) {
  1262. /* peer EDID has changed.
  1263. * toggle HPD to read EDID again
  1264. * In 8x30 FLUID HDMI HPD line
  1265. * is not connected
  1266. * with MHL 8334 transmitter
  1267. */
  1268. }
  1269. }
  1270. return 0;
  1271. }
  1272. static int mhl_msc_recv_write_stat(u8 offset, u8 value)
  1273. {
  1274. if (offset >= 2)
  1275. return -EFAULT;
  1276. switch (offset) {
  1277. case 0:
  1278. /* DCAP_RDY */
  1279. /*
  1280. * Connected Device bits changed and DEVCAP READY
  1281. */
  1282. pr_debug("MHL: value [0x%02x]\n", value);
  1283. pr_debug("MHL: offset [0x%02x]\n", offset);
  1284. pr_debug("MHL: devcap state [0x%02x]\n",
  1285. mhl_msm_state->devcap_state);
  1286. pr_debug("MHL: MHL_STATUS_DCAP_RDY [0x%02x]\n",
  1287. MHL_STATUS_DCAP_RDY);
  1288. if (((value ^ mhl_msm_state->devcap_state) &
  1289. MHL_STATUS_DCAP_RDY)) {
  1290. if (value & MHL_STATUS_DCAP_RDY) {
  1291. if (mhl_msc_read_devcap_all() == -EBUSY) {
  1292. pr_err("READ DEVCAP FAILED to send successfully\n");
  1293. break;
  1294. }
  1295. } else {
  1296. /* peer dcap turned not ready */
  1297. /*
  1298. * Clear DEVCAP READY state
  1299. */
  1300. }
  1301. }
  1302. break;
  1303. case 1:
  1304. /* PATH_EN */
  1305. /*
  1306. * Connected Device bits changed and PATH ENABLED
  1307. */
  1308. if ((value ^ mhl_msm_state->path_en_state)
  1309. & MHL_STATUS_PATH_ENABLED) {
  1310. if (value & MHL_STATUS_PATH_ENABLED) {
  1311. mhl_msm_state->path_en_state
  1312. |= (MHL_STATUS_PATH_ENABLED |
  1313. MHL_STATUS_CLK_MODE_NORMAL);
  1314. mhl_msc_send_write_stat(
  1315. MHL_STATUS_REG_LINK_MODE,
  1316. mhl_msm_state->path_en_state);
  1317. } else {
  1318. mhl_msm_state->path_en_state
  1319. &= ~(MHL_STATUS_PATH_ENABLED |
  1320. MHL_STATUS_CLK_MODE_NORMAL);
  1321. mhl_msc_send_write_stat(
  1322. MHL_STATUS_REG_LINK_MODE,
  1323. mhl_msm_state->path_en_state);
  1324. }
  1325. }
  1326. break;
  1327. }
  1328. mhl_msm_state->path_en_state = value;
  1329. return 0;
  1330. }
  1331. /* MSC, RCP, RAP messages - mandatory for compliance */
  1332. static void mhl_cbus_isr(void)
  1333. {
  1334. uint8_t regval;
  1335. int req_done = FALSE;
  1336. uint8_t sub_cmd = 0x0;
  1337. uint8_t cmd_data = 0x0;
  1338. int msc_msg_recved = FALSE;
  1339. int rc = -1;
  1340. regval = mhl_i2c_reg_read(TX_PAGE_CBUS, 0x08);
  1341. if (regval == 0xff)
  1342. return;
  1343. /*
  1344. * clear all interrupts that were raised
  1345. * even if we did not process
  1346. */
  1347. if (regval)
  1348. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x08, regval);
  1349. pr_debug("%s: CBUS_INT = %02x\n", __func__, regval);
  1350. /* MSC_MSG (RCP/RAP) */
  1351. if (regval & BIT3) {
  1352. sub_cmd = mhl_i2c_reg_read(TX_PAGE_CBUS, 0x18);
  1353. cmd_data = mhl_i2c_reg_read(TX_PAGE_CBUS, 0x19);
  1354. msc_msg_recved = TRUE;
  1355. }
  1356. /* MSC_MT_ABRT/MSC_MR_ABRT/DDC_ABORT */
  1357. if (regval & (BIT6 | BIT5 | BIT2))
  1358. mhl_cbus_process_errors(regval);
  1359. /* MSC_REQ_DONE */
  1360. if (regval & BIT4)
  1361. req_done = TRUE;
  1362. /* Now look for interrupts on CBUS_MSC_INT2 */
  1363. regval = mhl_i2c_reg_read(TX_PAGE_CBUS, 0x1E);
  1364. /* clear all interrupts that were raised */
  1365. /* even if we did not process */
  1366. if (regval)
  1367. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x1E, regval);
  1368. pr_debug("%s: CBUS_MSC_INT2 = %02x\n", __func__, regval);
  1369. /* received SET_INT */
  1370. if (regval & BIT2) {
  1371. uint8_t intr;
  1372. intr = mhl_i2c_reg_read(TX_PAGE_CBUS, 0xA0);
  1373. mhl_msc_recv_set_int(0, intr);
  1374. pr_debug("%s: MHL_INT_0 = %02x\n", __func__, intr);
  1375. intr = mhl_i2c_reg_read(TX_PAGE_CBUS, 0xA1);
  1376. mhl_msc_recv_set_int(1, intr);
  1377. pr_debug("%s: MHL_INT_1 = %02x\n", __func__, intr);
  1378. mhl_i2c_reg_write(TX_PAGE_CBUS, 0xA0, 0xFF);
  1379. mhl_i2c_reg_write(TX_PAGE_CBUS, 0xA1, 0xFF);
  1380. mhl_i2c_reg_write(TX_PAGE_CBUS, 0xA2, 0xFF);
  1381. mhl_i2c_reg_write(TX_PAGE_CBUS, 0xA3, 0xFF);
  1382. }
  1383. /* received WRITE_STAT */
  1384. if (regval & BIT3) {
  1385. uint8_t stat;
  1386. stat = mhl_i2c_reg_read(TX_PAGE_CBUS, 0xB0);
  1387. mhl_msc_recv_write_stat(0, stat);
  1388. pr_debug("%s: MHL_STATUS_0 = %02x\n", __func__, stat);
  1389. stat = mhl_i2c_reg_read(TX_PAGE_CBUS, 0xB1);
  1390. mhl_msc_recv_write_stat(1, stat);
  1391. pr_debug("%s: MHL_STATUS_1 = %02x\n", __func__, stat);
  1392. mhl_i2c_reg_write(TX_PAGE_CBUS, 0xB0, 0xFF);
  1393. mhl_i2c_reg_write(TX_PAGE_CBUS, 0xB1, 0xFF);
  1394. mhl_i2c_reg_write(TX_PAGE_CBUS, 0xB2, 0xFF);
  1395. mhl_i2c_reg_write(TX_PAGE_CBUS, 0xB3, 0xFF);
  1396. }
  1397. /* received MSC_MSG */
  1398. if (msc_msg_recved) {
  1399. /*mhl msc recv msc msg*/
  1400. rc = mhl_msc_recv_msc_msg(sub_cmd, cmd_data);
  1401. if (rc)
  1402. pr_err("MHL: mhl msc recv msc msg failed(%d)!\n", rc);
  1403. }
  1404. /* complete last command */
  1405. if (req_done)
  1406. complete_all(&mhl_msm_state->msc_cmd_done);
  1407. return;
  1408. }
  1409. static void clear_all_intrs(void)
  1410. {
  1411. uint8_t regval = 0x00;
  1412. /*
  1413. * intr status debug
  1414. */
  1415. pr_debug("********* EXITING ISR MASK CHECK ?? *************\n");
  1416. pr_debug("Drv: INT1 MASK = %02X\n",
  1417. (int) mhl_i2c_reg_read(TX_PAGE_L0, 0x0071));
  1418. pr_debug("Drv: INT3 MASK = %02X\n",
  1419. (int) mhl_i2c_reg_read(TX_PAGE_L0, 0x0077));
  1420. pr_debug("Drv: INT4 MASK = %02X\n",
  1421. (int) mhl_i2c_reg_read(TX_PAGE_3, 0x0021));
  1422. pr_debug("Drv: INT5 MASK = %02X\n",
  1423. (int) mhl_i2c_reg_read(TX_PAGE_3, 0x0023));
  1424. pr_debug("Drv: CBUS1 MASK = %02X\n",
  1425. (int) mhl_i2c_reg_read(TX_PAGE_CBUS, 0x0009));
  1426. pr_debug("Drv: CBUS2 MASK = %02X\n",
  1427. (int) mhl_i2c_reg_read(TX_PAGE_CBUS, 0x001F));
  1428. pr_debug("********* END OF ISR MASK CHECK *************\n");
  1429. pr_debug("********* EXITING IN ISR ?? *************\n");
  1430. regval = mhl_i2c_reg_read(TX_PAGE_L0, 0x0071);
  1431. pr_debug("Drv: INT1 Status = %02X\n", (int)regval);
  1432. mhl_i2c_reg_write(TX_PAGE_L0, 0x0071, regval);
  1433. regval = mhl_i2c_reg_read(TX_PAGE_L0, 0x0072);
  1434. pr_debug("Drv: INT2 Status = %02X\n", (int)regval);
  1435. mhl_i2c_reg_write(TX_PAGE_L0, 0x0072, regval);
  1436. regval = mhl_i2c_reg_read(TX_PAGE_L0, 0x0073);
  1437. pr_debug("Drv: INT3 Status = %02X\n", (int)regval);
  1438. mhl_i2c_reg_write(TX_PAGE_L0, 0x0073, regval);
  1439. regval = mhl_i2c_reg_read(TX_PAGE_3, 0x0021);
  1440. pr_debug("Drv: INT4 Status = %02X\n", (int)regval);
  1441. mhl_i2c_reg_write(TX_PAGE_3, 0x0021, regval);
  1442. regval = mhl_i2c_reg_read(TX_PAGE_3, 0x0023);
  1443. pr_debug("Drv: INT5 Status = %02X\n", (int)regval);
  1444. mhl_i2c_reg_write(TX_PAGE_3, 0x0023, regval);
  1445. regval = mhl_i2c_reg_read(TX_PAGE_CBUS, 0x0008);
  1446. pr_debug("Drv: cbusInt Status = %02X\n", (int)regval);
  1447. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x0008, regval);
  1448. regval = mhl_i2c_reg_read(TX_PAGE_CBUS, 0x001E);
  1449. pr_debug("Drv: CBUS INTR_2: %d\n", (int)regval);
  1450. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x001E, regval);
  1451. regval = mhl_i2c_reg_read(TX_PAGE_CBUS, 0x00A0);
  1452. pr_debug("Drv: A0 INT Set = %02X\n", (int)regval);
  1453. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x00A0, regval);
  1454. regval = mhl_i2c_reg_read(TX_PAGE_CBUS, 0x00A1);
  1455. pr_debug("Drv: A1 INT Set = %02X\n", (int)regval);
  1456. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x00A1, regval);
  1457. regval = mhl_i2c_reg_read(TX_PAGE_CBUS, 0x00A2);
  1458. pr_debug("Drv: A2 INT Set = %02X\n", (int)regval);
  1459. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x00A2, regval);
  1460. regval = mhl_i2c_reg_read(TX_PAGE_CBUS, 0x00A3);
  1461. pr_debug("Drv: A3 INT Set = %02X\n", (int)regval);
  1462. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x00A3, regval);
  1463. regval = mhl_i2c_reg_read(TX_PAGE_CBUS, 0x00B0);
  1464. pr_debug("Drv: B0 STATUS Set = %02X\n", (int)regval);
  1465. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x00B0, regval);
  1466. regval = mhl_i2c_reg_read(TX_PAGE_CBUS, 0x00B1);
  1467. pr_debug("Drv: B1 STATUS Set = %02X\n", (int)regval);
  1468. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x00B1, regval);
  1469. regval = mhl_i2c_reg_read(TX_PAGE_CBUS, 0x00B2);
  1470. pr_debug("Drv: B2 STATUS Set = %02X\n", (int)regval);
  1471. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x00B2, regval);
  1472. regval = mhl_i2c_reg_read(TX_PAGE_CBUS, 0x00B3);
  1473. pr_debug("Drv: B3 STATUS Set = %02X\n", (int)regval);
  1474. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x00B3, regval);
  1475. regval = mhl_i2c_reg_read(TX_PAGE_CBUS, 0x00E0);
  1476. pr_debug("Drv: E0 STATUS Set = %02X\n", (int)regval);
  1477. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x00E0, regval);
  1478. regval = mhl_i2c_reg_read(TX_PAGE_CBUS, 0x00E1);
  1479. pr_debug("Drv: E1 STATUS Set = %02X\n", (int)regval);
  1480. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x00E1, regval);
  1481. regval = mhl_i2c_reg_read(TX_PAGE_CBUS, 0x00E2);
  1482. pr_debug("Drv: E2 STATUS Set = %02X\n", (int)regval);
  1483. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x00E2, regval);
  1484. regval = mhl_i2c_reg_read(TX_PAGE_CBUS, 0x00E3);
  1485. pr_debug("Drv: E3 STATUS Set = %02X\n", (int)regval);
  1486. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x00E3, regval);
  1487. regval = mhl_i2c_reg_read(TX_PAGE_CBUS, 0x00F0);
  1488. pr_debug("Drv: F0 INT Set = %02X\n", (int)regval);
  1489. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x00F0, regval);
  1490. regval = mhl_i2c_reg_read(TX_PAGE_CBUS, 0x00F1);
  1491. pr_debug("Drv: F1 INT Set = %02X\n", (int)regval);
  1492. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x00F1, regval);
  1493. regval = mhl_i2c_reg_read(TX_PAGE_CBUS, 0x00F2);
  1494. pr_debug("Drv: F2 INT Set = %02X\n", (int)regval);
  1495. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x00F2, regval);
  1496. regval = mhl_i2c_reg_read(TX_PAGE_CBUS, 0x00F3);
  1497. pr_debug("Drv: F3 INT Set = %02X\n", (int)regval);
  1498. mhl_i2c_reg_write(TX_PAGE_CBUS, 0x00F3, regval);
  1499. pr_debug("********* END OF EXITING IN ISR *************\n");
  1500. }
  1501. static irqreturn_t mhl_tx_isr(int irq, void *dev_id)
  1502. {
  1503. /*
  1504. * Check RGND, MHL_EST, CBUS_LOCKOUT, SCDT
  1505. * interrupts. In D3, we get only RGND
  1506. */
  1507. int_4_isr();
  1508. pr_debug("MHL: Current POWER state is [0x%x]\n",
  1509. mhl_msm_state->cur_state);
  1510. if (mhl_msm_state->cur_state == POWER_STATE_D0_MHL) {
  1511. /*
  1512. * If int_4_isr() didn't move the tx to D3
  1513. * on disconnect, continue to check other
  1514. * interrupt sources.
  1515. */
  1516. int_5_isr();
  1517. /*
  1518. * Check for any peer messages for DCAP_CHG etc
  1519. * Dispatch to have the CBUS module working only
  1520. * once connected.
  1521. */
  1522. mhl_cbus_isr();
  1523. int_1_isr();
  1524. }
  1525. clear_all_intrs();
  1526. return IRQ_HANDLED;
  1527. }
  1528. static void __exit mhl_msm_exit(void)
  1529. {
  1530. pr_warn("MHL: Exiting, Bye\n");
  1531. /*
  1532. * Delete driver if i2c client structure is NULL
  1533. */
  1534. i2c_del_driver(&mhl_sii_i2c_driver);
  1535. if (!mhl_msm_state) {
  1536. kfree(mhl_msm_state);
  1537. mhl_msm_state = NULL;
  1538. }
  1539. }
  1540. module_init(mhl_msm_init);
  1541. module_exit(mhl_msm_exit);
  1542. MODULE_LICENSE("GPL v2");
  1543. MODULE_DESCRIPTION("MHL SII 8334 TX driver");