extcon-max77693.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918
  1. /*
  2. * extcon-max77693.c - MAX77693 extcon driver to support MAX77693 MUIC
  3. *
  4. * Copyright (C) 2012 Samsung Electrnoics
  5. * Chanwoo Choi <cw00.choi@samsung.com>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. */
  17. #include <linux/kernel.h>
  18. #include <linux/module.h>
  19. #include <linux/i2c.h>
  20. #include <linux/slab.h>
  21. #include <linux/interrupt.h>
  22. #include <linux/err.h>
  23. #include <linux/platform_device.h>
  24. #include <linux/mfd/max77693.h>
  25. #include <linux/mfd/max77693-private.h>
  26. #include <linux/extcon.h>
  27. #include <linux/regmap.h>
  28. #include <linux/irqdomain.h>
  29. #define DEV_NAME "max77693-muic"
  30. enum max77693_muic_adc_debounce_time {
  31. ADC_DEBOUNCE_TIME_5MS = 0,
  32. ADC_DEBOUNCE_TIME_10MS,
  33. ADC_DEBOUNCE_TIME_25MS,
  34. ADC_DEBOUNCE_TIME_38_62MS,
  35. };
  36. struct max77693_muic_info {
  37. struct device *dev;
  38. struct max77693_dev *max77693;
  39. struct extcon_dev *edev;
  40. int prev_cable_type;
  41. int prev_cable_type_gnd;
  42. int prev_chg_type;
  43. u8 status[2];
  44. int irq;
  45. struct work_struct irq_work;
  46. struct mutex mutex;
  47. };
  48. enum max77693_muic_cable_group {
  49. MAX77693_CABLE_GROUP_ADC = 0,
  50. MAX77693_CABLE_GROUP_ADC_GND,
  51. MAX77693_CABLE_GROUP_CHG,
  52. MAX77693_CABLE_GROUP_VBVOLT,
  53. };
  54. enum max77693_muic_charger_type {
  55. MAX77693_CHARGER_TYPE_NONE = 0,
  56. MAX77693_CHARGER_TYPE_USB,
  57. MAX77693_CHARGER_TYPE_DOWNSTREAM_PORT,
  58. MAX77693_CHARGER_TYPE_DEDICATED_CHG,
  59. MAX77693_CHARGER_TYPE_APPLE_500MA,
  60. MAX77693_CHARGER_TYPE_APPLE_1A_2A,
  61. MAX77693_CHARGER_TYPE_DEAD_BATTERY = 7,
  62. };
  63. /**
  64. * struct max77693_muic_irq
  65. * @irq: the index of irq list of MUIC device.
  66. * @name: the name of irq.
  67. * @virq: the virtual irq to use irq domain
  68. */
  69. struct max77693_muic_irq {
  70. unsigned int irq;
  71. const char *name;
  72. unsigned int virq;
  73. };
  74. static struct max77693_muic_irq muic_irqs[] = {
  75. { MAX77693_MUIC_IRQ_INT1_ADC, "muic-ADC" },
  76. { MAX77693_MUIC_IRQ_INT1_ADC_LOW, "muic-ADCLOW" },
  77. { MAX77693_MUIC_IRQ_INT1_ADC_ERR, "muic-ADCError" },
  78. { MAX77693_MUIC_IRQ_INT1_ADC1K, "muic-ADC1K" },
  79. { MAX77693_MUIC_IRQ_INT2_CHGTYP, "muic-CHGTYP" },
  80. { MAX77693_MUIC_IRQ_INT2_CHGDETREUN, "muic-CHGDETREUN" },
  81. { MAX77693_MUIC_IRQ_INT2_DCDTMR, "muic-DCDTMR" },
  82. { MAX77693_MUIC_IRQ_INT2_DXOVP, "muic-DXOVP" },
  83. { MAX77693_MUIC_IRQ_INT2_VBVOLT, "muic-VBVOLT" },
  84. { MAX77693_MUIC_IRQ_INT2_VIDRM, "muic-VIDRM" },
  85. { MAX77693_MUIC_IRQ_INT3_EOC, "muic-EOC" },
  86. { MAX77693_MUIC_IRQ_INT3_CGMBC, "muic-CGMBC" },
  87. { MAX77693_MUIC_IRQ_INT3_OVP, "muic-OVP" },
  88. { MAX77693_MUIC_IRQ_INT3_MBCCHG_ERR, "muic-MBCCHG_ERR" },
  89. { MAX77693_MUIC_IRQ_INT3_CHG_ENABLED, "muic-CHG_ENABLED" },
  90. { MAX77693_MUIC_IRQ_INT3_BAT_DET, "muic-BAT_DET" },
  91. };
  92. /* Define supported accessory type */
  93. enum max77693_muic_acc_type {
  94. MAX77693_MUIC_ADC_GROUND = 0x0,
  95. MAX77693_MUIC_ADC_SEND_END_BUTTON,
  96. MAX77693_MUIC_ADC_REMOTE_S1_BUTTON,
  97. MAX77693_MUIC_ADC_REMOTE_S2_BUTTON,
  98. MAX77693_MUIC_ADC_REMOTE_S3_BUTTON,
  99. MAX77693_MUIC_ADC_REMOTE_S4_BUTTON,
  100. MAX77693_MUIC_ADC_REMOTE_S5_BUTTON,
  101. MAX77693_MUIC_ADC_REMOTE_S6_BUTTON,
  102. MAX77693_MUIC_ADC_REMOTE_S7_BUTTON,
  103. MAX77693_MUIC_ADC_REMOTE_S8_BUTTON,
  104. MAX77693_MUIC_ADC_REMOTE_S9_BUTTON,
  105. MAX77693_MUIC_ADC_REMOTE_S10_BUTTON,
  106. MAX77693_MUIC_ADC_REMOTE_S11_BUTTON,
  107. MAX77693_MUIC_ADC_REMOTE_S12_BUTTON,
  108. MAX77693_MUIC_ADC_RESERVED_ACC_1,
  109. MAX77693_MUIC_ADC_RESERVED_ACC_2,
  110. MAX77693_MUIC_ADC_RESERVED_ACC_3,
  111. MAX77693_MUIC_ADC_RESERVED_ACC_4,
  112. MAX77693_MUIC_ADC_RESERVED_ACC_5,
  113. MAX77693_MUIC_ADC_CEA936_AUDIO,
  114. MAX77693_MUIC_ADC_PHONE_POWERED_DEV,
  115. MAX77693_MUIC_ADC_TTY_CONVERTER,
  116. MAX77693_MUIC_ADC_UART_CABLE,
  117. MAX77693_MUIC_ADC_CEA936A_TYPE1_CHG,
  118. MAX77693_MUIC_ADC_FACTORY_MODE_USB_OFF,
  119. MAX77693_MUIC_ADC_FACTORY_MODE_USB_ON,
  120. MAX77693_MUIC_ADC_AV_CABLE_NOLOAD,
  121. MAX77693_MUIC_ADC_CEA936A_TYPE2_CHG,
  122. MAX77693_MUIC_ADC_FACTORY_MODE_UART_OFF,
  123. MAX77693_MUIC_ADC_FACTORY_MODE_UART_ON,
  124. MAX77693_MUIC_ADC_AUDIO_MODE_REMOTE,
  125. MAX77693_MUIC_ADC_OPEN,
  126. /* The below accessories have same ADC value so ADCLow and
  127. ADC1K bit is used to separate specific accessory */
  128. MAX77693_MUIC_GND_USB_OTG = 0x100, /* ADC:0x0, VBVolot:0, ADCLow:0, ADC1K:0 */
  129. MAX77693_MUIC_GND_USB_OTG_VB = 0x104, /* ADC:0x0, VBVolot:1, ADCLow:0, ADC1K:0 */
  130. MAX77693_MUIC_GND_AV_CABLE_LOAD = 0x102,/* ADC:0x0, VBVolot:0, ADCLow:1, ADC1K:0 */
  131. MAX77693_MUIC_GND_MHL = 0x103, /* ADC:0x0, VBVolot:0, ADCLow:1, ADC1K:1 */
  132. MAX77693_MUIC_GND_MHL_VB = 0x107, /* ADC:0x0, VBVolot:1, ADCLow:1, ADC1K:1 */
  133. };
  134. /* MAX77693 MUIC device support below list of accessories(external connector) */
  135. enum {
  136. EXTCON_CABLE_USB = 0,
  137. EXTCON_CABLE_USB_HOST,
  138. EXTCON_CABLE_TA,
  139. EXTCON_CABLE_FAST_CHARGER,
  140. EXTCON_CABLE_SLOW_CHARGER,
  141. EXTCON_CABLE_CHARGE_DOWNSTREAM,
  142. EXTCON_CABLE_MHL,
  143. EXTCON_CABLE_MHL_TA,
  144. EXTCON_CABLE_JIG_USB_ON,
  145. EXTCON_CABLE_JIG_USB_OFF,
  146. EXTCON_CABLE_JIG_UART_OFF,
  147. EXTCON_CABLE_AUDIO_VIDEO_LOAD,
  148. _EXTCON_CABLE_NUM,
  149. };
  150. const char *max77693_extcon_cable[] = {
  151. [EXTCON_CABLE_USB] = "USB",
  152. [EXTCON_CABLE_USB_HOST] = "USB-Host",
  153. [EXTCON_CABLE_TA] = "TA",
  154. [EXTCON_CABLE_FAST_CHARGER] = "Fast-charger",
  155. [EXTCON_CABLE_SLOW_CHARGER] = "Slow-charger",
  156. [EXTCON_CABLE_CHARGE_DOWNSTREAM] = "Charge-downstream",
  157. [EXTCON_CABLE_MHL] = "MHL",
  158. [EXTCON_CABLE_MHL_TA] = "MHL_TA",
  159. [EXTCON_CABLE_JIG_USB_ON] = "JIG-USB-ON",
  160. [EXTCON_CABLE_JIG_USB_OFF] = "JIG-USB-OFF",
  161. [EXTCON_CABLE_JIG_UART_OFF] = "JIG-UART-OFF",
  162. [EXTCON_CABLE_AUDIO_VIDEO_LOAD] = "Audio-video-load",
  163. NULL,
  164. };
  165. /*
  166. * max77693_muic_set_debounce_time - Set the debounce time of ADC
  167. * @info: the instance including private data of max77693 MUIC
  168. * @time: the debounce time of ADC
  169. */
  170. static int max77693_muic_set_debounce_time(struct max77693_muic_info *info,
  171. enum max77693_muic_adc_debounce_time time)
  172. {
  173. int ret;
  174. switch (time) {
  175. case ADC_DEBOUNCE_TIME_5MS:
  176. case ADC_DEBOUNCE_TIME_10MS:
  177. case ADC_DEBOUNCE_TIME_25MS:
  178. case ADC_DEBOUNCE_TIME_38_62MS:
  179. ret = max77693_update_reg(info->max77693->regmap_muic,
  180. MAX77693_MUIC_REG_CTRL3,
  181. time << CONTROL3_ADCDBSET_SHIFT,
  182. CONTROL3_ADCDBSET_MASK);
  183. if (ret)
  184. dev_err(info->dev, "failed to set ADC debounce time\n");
  185. break;
  186. default:
  187. dev_err(info->dev, "invalid ADC debounce time\n");
  188. ret = -EINVAL;
  189. break;
  190. }
  191. return ret;
  192. };
  193. /*
  194. * max77693_muic_set_path - Set hardware line according to attached cable
  195. * @info: the instance including private data of max77693 MUIC
  196. * @value: the path according to attached cable
  197. * @attached: the state of cable (true:attached, false:detached)
  198. *
  199. * The max77693 MUIC device share outside H/W line among a varity of cables
  200. * so, this function set internal path of H/W line according to the type of
  201. * attached cable.
  202. */
  203. static int max77693_muic_set_path(struct max77693_muic_info *info,
  204. u8 val, bool attached)
  205. {
  206. int ret = 0;
  207. u8 ctrl1, ctrl2 = 0;
  208. if (attached)
  209. ctrl1 = val;
  210. else
  211. ctrl1 = CONTROL1_SW_OPEN;
  212. ret = max77693_update_reg(info->max77693->regmap_muic,
  213. MAX77693_MUIC_REG_CTRL1, ctrl1, COMP_SW_MASK);
  214. if (ret < 0) {
  215. dev_err(info->dev, "failed to update MUIC register\n");
  216. goto out;
  217. }
  218. if (attached)
  219. ctrl2 |= CONTROL2_CPEN_MASK; /* LowPwr=0, CPEn=1 */
  220. else
  221. ctrl2 |= CONTROL2_LOWPWR_MASK; /* LowPwr=1, CPEn=0 */
  222. ret = max77693_update_reg(info->max77693->regmap_muic,
  223. MAX77693_MUIC_REG_CTRL2, ctrl2,
  224. CONTROL2_LOWPWR_MASK | CONTROL2_CPEN_MASK);
  225. if (ret < 0) {
  226. dev_err(info->dev, "failed to update MUIC register\n");
  227. goto out;
  228. }
  229. dev_info(info->dev,
  230. "CONTROL1 : 0x%02x, CONTROL2 : 0x%02x, state : %s\n",
  231. ctrl1, ctrl2, attached ? "attached" : "detached");
  232. out:
  233. return ret;
  234. }
  235. /*
  236. * max77693_muic_get_cable_type - Return cable type and check cable state
  237. * @info: the instance including private data of max77693 MUIC
  238. * @group: the path according to attached cable
  239. * @attached: store cable state and return
  240. *
  241. * This function check the cable state either attached or detached,
  242. * and then divide precise type of cable according to cable group.
  243. * - MAX77693_CABLE_GROUP_ADC
  244. * - MAX77693_CABLE_GROUP_ADC_GND
  245. * - MAX77693_CABLE_GROUP_CHG
  246. * - MAX77693_CABLE_GROUP_VBVOLT
  247. */
  248. static int max77693_muic_get_cable_type(struct max77693_muic_info *info,
  249. enum max77693_muic_cable_group group, bool *attached)
  250. {
  251. int cable_type = 0;
  252. int adc;
  253. int adc1k;
  254. int adclow;
  255. int vbvolt;
  256. int chg_type;
  257. switch (group) {
  258. case MAX77693_CABLE_GROUP_ADC:
  259. /*
  260. * Read ADC value to check cable type and decide cable state
  261. * according to cable type
  262. */
  263. adc = info->status[0] & STATUS1_ADC_MASK;
  264. adc >>= STATUS1_ADC_SHIFT;
  265. /*
  266. * Check current cable state/cable type and store cable type
  267. * (info->prev_cable_type) for handling cable when cable is
  268. * detached.
  269. */
  270. if (adc == MAX77693_MUIC_ADC_OPEN) {
  271. *attached = false;
  272. cable_type = info->prev_cable_type;
  273. info->prev_cable_type = MAX77693_MUIC_ADC_OPEN;
  274. } else {
  275. *attached = true;
  276. cable_type = info->prev_cable_type = adc;
  277. }
  278. break;
  279. case MAX77693_CABLE_GROUP_ADC_GND:
  280. /*
  281. * Read ADC value to check cable type and decide cable state
  282. * according to cable type
  283. */
  284. adc = info->status[0] & STATUS1_ADC_MASK;
  285. adc >>= STATUS1_ADC_SHIFT;
  286. /*
  287. * Check current cable state/cable type and store cable type
  288. * (info->prev_cable_type/_gnd) for handling cable when cable
  289. * is detached.
  290. */
  291. if (adc == MAX77693_MUIC_ADC_OPEN) {
  292. *attached = false;
  293. cable_type = info->prev_cable_type_gnd;
  294. info->prev_cable_type_gnd = MAX77693_MUIC_ADC_OPEN;
  295. } else {
  296. *attached = true;
  297. adclow = info->status[0] & STATUS1_ADCLOW_MASK;
  298. adclow >>= STATUS1_ADCLOW_SHIFT;
  299. adc1k = info->status[0] & STATUS1_ADC1K_MASK;
  300. adc1k >>= STATUS1_ADC1K_SHIFT;
  301. vbvolt = info->status[1] & STATUS2_VBVOLT_MASK;
  302. vbvolt >>= STATUS2_VBVOLT_SHIFT;
  303. /**
  304. * [0x1][VBVolt][ADCLow][ADC1K]
  305. * [0x1 0 0 0 ] : USB_OTG
  306. * [0x1 1 0 0 ] : USB_OTG_VB
  307. * [0x1 0 1 0 ] : Audio Video Cable with load
  308. * [0x1 0 1 1 ] : MHL without charging connector
  309. * [0x1 1 1 1 ] : MHL with charging connector
  310. */
  311. cable_type = ((0x1 << 8)
  312. | (vbvolt << 2)
  313. | (adclow << 1)
  314. | adc1k);
  315. info->prev_cable_type = adc;
  316. info->prev_cable_type_gnd = cable_type;
  317. }
  318. break;
  319. case MAX77693_CABLE_GROUP_CHG:
  320. /*
  321. * Read charger type to check cable type and decide cable state
  322. * according to type of charger cable.
  323. */
  324. chg_type = info->status[1] & STATUS2_CHGTYP_MASK;
  325. chg_type >>= STATUS2_CHGTYP_SHIFT;
  326. if (chg_type == MAX77693_CHARGER_TYPE_NONE) {
  327. *attached = false;
  328. cable_type = info->prev_chg_type;
  329. info->prev_chg_type = MAX77693_CHARGER_TYPE_NONE;
  330. } else {
  331. *attached = true;
  332. /*
  333. * Check current cable state/cable type and store cable
  334. * type(info->prev_chg_type) for handling cable when
  335. * charger cable is detached.
  336. */
  337. cable_type = info->prev_chg_type = chg_type;
  338. }
  339. break;
  340. case MAX77693_CABLE_GROUP_VBVOLT:
  341. /*
  342. * Read ADC value to check cable type and decide cable state
  343. * according to cable type
  344. */
  345. adc = info->status[0] & STATUS1_ADC_MASK;
  346. adc >>= STATUS1_ADC_SHIFT;
  347. chg_type = info->status[1] & STATUS2_CHGTYP_MASK;
  348. chg_type >>= STATUS2_CHGTYP_SHIFT;
  349. if (adc == MAX77693_MUIC_ADC_OPEN
  350. && chg_type == MAX77693_CHARGER_TYPE_NONE)
  351. *attached = false;
  352. else
  353. *attached = true;
  354. /*
  355. * Read vbvolt field, if vbvolt is 1,
  356. * this cable is used for charging.
  357. */
  358. vbvolt = info->status[1] & STATUS2_VBVOLT_MASK;
  359. vbvolt >>= STATUS2_VBVOLT_SHIFT;
  360. cable_type = vbvolt;
  361. break;
  362. default:
  363. dev_err(info->dev, "Unknown cable group (%d)\n", group);
  364. cable_type = -EINVAL;
  365. break;
  366. }
  367. return cable_type;
  368. }
  369. static int max77693_muic_adc_ground_handler(struct max77693_muic_info *info)
  370. {
  371. int cable_type_gnd;
  372. int ret = 0;
  373. bool attached;
  374. cable_type_gnd = max77693_muic_get_cable_type(info,
  375. MAX77693_CABLE_GROUP_ADC_GND, &attached);
  376. switch (cable_type_gnd) {
  377. case MAX77693_MUIC_GND_USB_OTG:
  378. case MAX77693_MUIC_GND_USB_OTG_VB:
  379. /* USB_OTG, PATH: AP_USB */
  380. ret = max77693_muic_set_path(info, CONTROL1_SW_USB, attached);
  381. if (ret < 0)
  382. goto out;
  383. extcon_set_cable_state(info->edev, "USB-Host", attached);
  384. break;
  385. case MAX77693_MUIC_GND_AV_CABLE_LOAD:
  386. /* Audio Video Cable with load, PATH:AUDIO */
  387. ret = max77693_muic_set_path(info, CONTROL1_SW_AUDIO, attached);
  388. if (ret < 0)
  389. goto out;
  390. extcon_set_cable_state(info->edev,
  391. "Audio-video-load", attached);
  392. break;
  393. case MAX77693_MUIC_GND_MHL:
  394. case MAX77693_MUIC_GND_MHL_VB:
  395. /* MHL or MHL with USB/TA cable */
  396. extcon_set_cable_state(info->edev, "MHL", attached);
  397. break;
  398. default:
  399. dev_err(info->dev, "failed to detect %s accessory\n",
  400. attached ? "attached" : "detached");
  401. ret = -EINVAL;
  402. break;
  403. }
  404. out:
  405. return ret;
  406. }
  407. static int max77693_muic_jig_handler(struct max77693_muic_info *info,
  408. int cable_type, bool attached)
  409. {
  410. char cable_name[32];
  411. int ret = 0;
  412. u8 path = CONTROL1_SW_OPEN;
  413. dev_info(info->dev,
  414. "external connector is %s (adc:0x%02x)\n",
  415. attached ? "attached" : "detached", cable_type);
  416. switch (cable_type) {
  417. case MAX77693_MUIC_ADC_FACTORY_MODE_USB_OFF: /* ADC_JIG_USB_OFF */
  418. /* PATH:AP_USB */
  419. strcpy(cable_name, "JIG-USB-OFF");
  420. path = CONTROL1_SW_USB;
  421. break;
  422. case MAX77693_MUIC_ADC_FACTORY_MODE_USB_ON: /* ADC_JIG_USB_ON */
  423. /* PATH:AP_USB */
  424. strcpy(cable_name, "JIG-USB-ON");
  425. path = CONTROL1_SW_USB;
  426. break;
  427. case MAX77693_MUIC_ADC_FACTORY_MODE_UART_OFF: /* ADC_JIG_UART_OFF */
  428. /* PATH:AP_UART */
  429. strcpy(cable_name, "JIG-UART-OFF");
  430. path = CONTROL1_SW_UART;
  431. break;
  432. }
  433. ret = max77693_muic_set_path(info, path, attached);
  434. if (ret < 0)
  435. goto out;
  436. extcon_set_cable_state(info->edev, cable_name, attached);
  437. out:
  438. return ret;
  439. }
  440. static int max77693_muic_adc_handler(struct max77693_muic_info *info)
  441. {
  442. int cable_type;
  443. bool attached;
  444. int ret = 0;
  445. /* Check accessory state which is either detached or attached */
  446. cable_type = max77693_muic_get_cable_type(info,
  447. MAX77693_CABLE_GROUP_ADC, &attached);
  448. dev_info(info->dev,
  449. "external connector is %s (adc:0x%02x, prev_adc:0x%x)\n",
  450. attached ? "attached" : "detached", cable_type,
  451. info->prev_cable_type);
  452. switch (cable_type) {
  453. case MAX77693_MUIC_ADC_GROUND:
  454. /* USB_OTG/MHL/Audio */
  455. max77693_muic_adc_ground_handler(info);
  456. break;
  457. case MAX77693_MUIC_ADC_FACTORY_MODE_USB_OFF:
  458. case MAX77693_MUIC_ADC_FACTORY_MODE_USB_ON:
  459. case MAX77693_MUIC_ADC_FACTORY_MODE_UART_OFF:
  460. /* JIG */
  461. ret = max77693_muic_jig_handler(info, cable_type, attached);
  462. if (ret < 0)
  463. goto out;
  464. break;
  465. case MAX77693_MUIC_ADC_FACTORY_MODE_UART_ON:
  466. case MAX77693_MUIC_ADC_AUDIO_MODE_REMOTE:
  467. /* Audio Video cable with no-load */
  468. ret = max77693_muic_set_path(info, CONTROL1_SW_AUDIO, attached);
  469. if (ret < 0)
  470. goto out;
  471. extcon_set_cable_state(info->edev,
  472. "Audio-video-noload", attached);
  473. break;
  474. case MAX77693_MUIC_ADC_SEND_END_BUTTON:
  475. case MAX77693_MUIC_ADC_REMOTE_S1_BUTTON:
  476. case MAX77693_MUIC_ADC_REMOTE_S2_BUTTON:
  477. case MAX77693_MUIC_ADC_REMOTE_S3_BUTTON:
  478. case MAX77693_MUIC_ADC_REMOTE_S4_BUTTON:
  479. case MAX77693_MUIC_ADC_REMOTE_S5_BUTTON:
  480. case MAX77693_MUIC_ADC_REMOTE_S6_BUTTON:
  481. case MAX77693_MUIC_ADC_REMOTE_S7_BUTTON:
  482. case MAX77693_MUIC_ADC_REMOTE_S8_BUTTON:
  483. case MAX77693_MUIC_ADC_REMOTE_S9_BUTTON:
  484. case MAX77693_MUIC_ADC_REMOTE_S10_BUTTON:
  485. case MAX77693_MUIC_ADC_REMOTE_S11_BUTTON:
  486. case MAX77693_MUIC_ADC_REMOTE_S12_BUTTON:
  487. case MAX77693_MUIC_ADC_RESERVED_ACC_1:
  488. case MAX77693_MUIC_ADC_RESERVED_ACC_2:
  489. case MAX77693_MUIC_ADC_RESERVED_ACC_3:
  490. case MAX77693_MUIC_ADC_RESERVED_ACC_4:
  491. case MAX77693_MUIC_ADC_RESERVED_ACC_5:
  492. case MAX77693_MUIC_ADC_CEA936_AUDIO:
  493. case MAX77693_MUIC_ADC_PHONE_POWERED_DEV:
  494. case MAX77693_MUIC_ADC_TTY_CONVERTER:
  495. case MAX77693_MUIC_ADC_UART_CABLE:
  496. case MAX77693_MUIC_ADC_CEA936A_TYPE1_CHG:
  497. case MAX77693_MUIC_ADC_AV_CABLE_NOLOAD:
  498. case MAX77693_MUIC_ADC_CEA936A_TYPE2_CHG:
  499. /* This accessory isn't used in general case if it is specially
  500. needed to detect additional accessory, should implement
  501. proper operation when this accessory is attached/detached. */
  502. dev_info(info->dev,
  503. "accessory is %s but it isn't used (adc:0x%x)\n",
  504. attached ? "attached" : "detached", cable_type);
  505. goto out;
  506. default:
  507. dev_err(info->dev,
  508. "failed to detect %s accessory (adc:0x%x)\n",
  509. attached ? "attached" : "detached", cable_type);
  510. ret = -EINVAL;
  511. goto out;
  512. }
  513. out:
  514. return ret;
  515. }
  516. static int max77693_muic_chg_handler(struct max77693_muic_info *info)
  517. {
  518. int chg_type;
  519. int cable_type_gnd;
  520. bool attached;
  521. bool cable_attached;
  522. int ret = 0;
  523. chg_type = max77693_muic_get_cable_type(info,
  524. MAX77693_CABLE_GROUP_CHG, &attached);
  525. dev_info(info->dev,
  526. "external connector is %s(chg_type:0x%x, prev_chg_type:0x%x)\n",
  527. attached ? "attached" : "detached",
  528. chg_type, info->prev_chg_type);
  529. switch (chg_type) {
  530. case MAX77693_CHARGER_TYPE_USB:
  531. cable_type_gnd = max77693_muic_get_cable_type(info,
  532. MAX77693_CABLE_GROUP_ADC_GND,
  533. &cable_attached);
  534. switch (cable_type_gnd) {
  535. case MAX77693_MUIC_GND_MHL:
  536. case MAX77693_MUIC_GND_MHL_VB:
  537. /*
  538. * USB/TA with MHL cable
  539. * - MHL cable, which connect micro USB or TA cable,
  540. * is used to charging battery. So, extcon driver check
  541. * charging type whether micro USB or TA cable is
  542. * connected to MHL cable when extcon driver detect MHL
  543. * cable.
  544. */
  545. extcon_set_cable_state(info->edev, "MHL_TA", attached);
  546. if (!cable_attached)
  547. extcon_set_cable_state(info->edev,
  548. "MHL", false);
  549. break;
  550. default:
  551. /* Only USB cable, PATH:AP_USB */
  552. ret = max77693_muic_set_path(info, CONTROL1_SW_USB,
  553. attached);
  554. if (ret < 0)
  555. goto out;
  556. extcon_set_cable_state(info->edev, "USB", attached);
  557. }
  558. break;
  559. case MAX77693_CHARGER_TYPE_DOWNSTREAM_PORT:
  560. extcon_set_cable_state(info->edev,
  561. "Charge-downstream", attached);
  562. break;
  563. case MAX77693_CHARGER_TYPE_DEDICATED_CHG:
  564. extcon_set_cable_state(info->edev, "TA", attached);
  565. break;
  566. case MAX77693_CHARGER_TYPE_APPLE_500MA:
  567. extcon_set_cable_state(info->edev, "Slow-charger", attached);
  568. break;
  569. case MAX77693_CHARGER_TYPE_APPLE_1A_2A:
  570. extcon_set_cable_state(info->edev, "Fast-charger", attached);
  571. break;
  572. case MAX77693_CHARGER_TYPE_DEAD_BATTERY:
  573. break;
  574. default:
  575. dev_err(info->dev,
  576. "failed to detect %s accessory (chg_type:0x%x)\n",
  577. attached ? "attached" : "detached", chg_type);
  578. ret = -EINVAL;
  579. goto out;
  580. }
  581. out:
  582. return ret;
  583. }
  584. static void max77693_muic_irq_work(struct work_struct *work)
  585. {
  586. struct max77693_muic_info *info = container_of(work,
  587. struct max77693_muic_info, irq_work);
  588. int irq_type = -1;
  589. int i, ret = 0;
  590. if (!info->edev)
  591. return;
  592. mutex_lock(&info->mutex);
  593. for (i = 0 ; i < ARRAY_SIZE(muic_irqs) ; i++)
  594. if (info->irq == muic_irqs[i].virq)
  595. irq_type = muic_irqs[i].irq;
  596. ret = max77693_bulk_read(info->max77693->regmap_muic,
  597. MAX77693_MUIC_REG_STATUS1, 2, info->status);
  598. if (ret) {
  599. dev_err(info->dev, "failed to read MUIC register\n");
  600. mutex_unlock(&info->mutex);
  601. return;
  602. }
  603. switch (irq_type) {
  604. case MAX77693_MUIC_IRQ_INT1_ADC:
  605. case MAX77693_MUIC_IRQ_INT1_ADC_LOW:
  606. case MAX77693_MUIC_IRQ_INT1_ADC_ERR:
  607. case MAX77693_MUIC_IRQ_INT1_ADC1K:
  608. /* Handle all of accessory except for
  609. type of charger accessory */
  610. ret = max77693_muic_adc_handler(info);
  611. break;
  612. case MAX77693_MUIC_IRQ_INT2_CHGTYP:
  613. case MAX77693_MUIC_IRQ_INT2_CHGDETREUN:
  614. case MAX77693_MUIC_IRQ_INT2_DCDTMR:
  615. case MAX77693_MUIC_IRQ_INT2_DXOVP:
  616. case MAX77693_MUIC_IRQ_INT2_VBVOLT:
  617. case MAX77693_MUIC_IRQ_INT2_VIDRM:
  618. /* Handle charger accessory */
  619. ret = max77693_muic_chg_handler(info);
  620. break;
  621. case MAX77693_MUIC_IRQ_INT3_EOC:
  622. case MAX77693_MUIC_IRQ_INT3_CGMBC:
  623. case MAX77693_MUIC_IRQ_INT3_OVP:
  624. case MAX77693_MUIC_IRQ_INT3_MBCCHG_ERR:
  625. case MAX77693_MUIC_IRQ_INT3_CHG_ENABLED:
  626. case MAX77693_MUIC_IRQ_INT3_BAT_DET:
  627. break;
  628. default:
  629. dev_err(info->dev, "muic interrupt: irq %d occurred\n",
  630. irq_type);
  631. break;
  632. }
  633. if (ret < 0)
  634. dev_err(info->dev, "failed to handle MUIC interrupt\n");
  635. mutex_unlock(&info->mutex);
  636. return;
  637. }
  638. static irqreturn_t max77693_muic_irq_handler(int irq, void *data)
  639. {
  640. struct max77693_muic_info *info = data;
  641. info->irq = irq;
  642. schedule_work(&info->irq_work);
  643. return IRQ_HANDLED;
  644. }
  645. static struct regmap_config max77693_muic_regmap_config = {
  646. .reg_bits = 8,
  647. .val_bits = 8,
  648. };
  649. static int max77693_muic_detect_accessory(struct max77693_muic_info *info)
  650. {
  651. int ret = 0;
  652. int adc;
  653. int chg_type;
  654. bool attached;
  655. mutex_lock(&info->mutex);
  656. /* Read STATUSx register to detect accessory */
  657. ret = max77693_bulk_read(info->max77693->regmap_muic,
  658. MAX77693_MUIC_REG_STATUS1, 2, info->status);
  659. if (ret) {
  660. dev_err(info->dev, "failed to read MUIC register\n");
  661. mutex_unlock(&info->mutex);
  662. return -EINVAL;
  663. }
  664. adc = max77693_muic_get_cable_type(info, MAX77693_CABLE_GROUP_ADC,
  665. &attached);
  666. if (attached && adc != MAX77693_MUIC_ADC_OPEN) {
  667. ret = max77693_muic_adc_handler(info);
  668. if (ret < 0)
  669. dev_err(info->dev, "Cannot detect accessory\n");
  670. }
  671. chg_type = max77693_muic_get_cable_type(info, MAX77693_CABLE_GROUP_CHG,
  672. &attached);
  673. if (attached && chg_type != MAX77693_CHARGER_TYPE_NONE) {
  674. ret = max77693_muic_chg_handler(info);
  675. if (ret < 0)
  676. dev_err(info->dev, "Cannot detect charger accessory\n");
  677. }
  678. mutex_unlock(&info->mutex);
  679. return ret;
  680. }
  681. static int max77693_muic_probe(struct platform_device *pdev)
  682. {
  683. struct max77693_dev *max77693 = dev_get_drvdata(pdev->dev.parent);
  684. struct max77693_platform_data *pdata = dev_get_platdata(max77693->dev);
  685. struct max77693_muic_platform_data *muic_pdata = pdata->muic_data;
  686. struct max77693_muic_info *info;
  687. int ret, i;
  688. u8 id;
  689. info = devm_kzalloc(&pdev->dev, sizeof(struct max77693_muic_info),
  690. GFP_KERNEL);
  691. if (!info) {
  692. dev_err(&pdev->dev, "failed to allocate memory\n");
  693. return -ENOMEM;
  694. }
  695. info->dev = &pdev->dev;
  696. info->max77693 = max77693;
  697. if (info->max77693->regmap_muic) {
  698. dev_dbg(&pdev->dev, "allocate register map\n");
  699. } else {
  700. info->max77693->regmap_muic = devm_regmap_init_i2c(
  701. info->max77693->muic,
  702. &max77693_muic_regmap_config);
  703. if (IS_ERR(info->max77693->regmap_muic)) {
  704. ret = PTR_ERR(info->max77693->regmap_muic);
  705. dev_err(max77693->dev,
  706. "failed to allocate register map: %d\n", ret);
  707. return ret;
  708. }
  709. }
  710. platform_set_drvdata(pdev, info);
  711. mutex_init(&info->mutex);
  712. INIT_WORK(&info->irq_work, max77693_muic_irq_work);
  713. /* Support irq domain for MAX77693 MUIC device */
  714. for (i = 0; i < ARRAY_SIZE(muic_irqs); i++) {
  715. struct max77693_muic_irq *muic_irq = &muic_irqs[i];
  716. unsigned int virq = 0;
  717. virq = irq_create_mapping(max77693->irq_domain, muic_irq->irq);
  718. if (!virq) {
  719. ret = -EINVAL;
  720. goto err_irq;
  721. }
  722. muic_irq->virq = virq;
  723. ret = request_threaded_irq(virq, NULL,
  724. max77693_muic_irq_handler,
  725. IRQF_ONESHOT, muic_irq->name, info);
  726. if (ret) {
  727. dev_err(&pdev->dev,
  728. "failed: irq request (IRQ: %d,"
  729. " error :%d)\n",
  730. muic_irq->irq, ret);
  731. goto err_irq;
  732. }
  733. }
  734. /* Initialize extcon device */
  735. info->edev = devm_kzalloc(&pdev->dev, sizeof(struct extcon_dev),
  736. GFP_KERNEL);
  737. if (!info->edev) {
  738. dev_err(&pdev->dev, "failed to allocate memory for extcon\n");
  739. ret = -ENOMEM;
  740. goto err_irq;
  741. }
  742. info->edev->name = DEV_NAME;
  743. info->edev->supported_cable = max77693_extcon_cable;
  744. ret = extcon_dev_register(info->edev, NULL);
  745. if (ret) {
  746. dev_err(&pdev->dev, "failed to register extcon device\n");
  747. goto err_irq;
  748. }
  749. /* Initialize MUIC register by using platform data */
  750. for (i = 0 ; i < muic_pdata->num_init_data ; i++) {
  751. enum max77693_irq_source irq_src = MAX77693_IRQ_GROUP_NR;
  752. max77693_write_reg(info->max77693->regmap_muic,
  753. muic_pdata->init_data[i].addr,
  754. muic_pdata->init_data[i].data);
  755. switch (muic_pdata->init_data[i].addr) {
  756. case MAX77693_MUIC_REG_INTMASK1:
  757. irq_src = MUIC_INT1;
  758. break;
  759. case MAX77693_MUIC_REG_INTMASK2:
  760. irq_src = MUIC_INT2;
  761. break;
  762. case MAX77693_MUIC_REG_INTMASK3:
  763. irq_src = MUIC_INT3;
  764. break;
  765. }
  766. if (irq_src < MAX77693_IRQ_GROUP_NR)
  767. info->max77693->irq_masks_cur[irq_src]
  768. = muic_pdata->init_data[i].data;
  769. }
  770. /* Check revision number of MUIC device*/
  771. ret = max77693_read_reg(info->max77693->regmap_muic,
  772. MAX77693_MUIC_REG_ID, &id);
  773. if (ret < 0) {
  774. dev_err(&pdev->dev, "failed to read revision number\n");
  775. goto err_irq;
  776. }
  777. dev_info(info->dev, "device ID : 0x%x\n", id);
  778. /* Set ADC debounce time */
  779. max77693_muic_set_debounce_time(info, ADC_DEBOUNCE_TIME_25MS);
  780. /* Detect accessory on boot */
  781. max77693_muic_detect_accessory(info);
  782. return ret;
  783. err_irq:
  784. while (--i >= 0)
  785. free_irq(muic_irqs[i].virq, info);
  786. return ret;
  787. }
  788. static int max77693_muic_remove(struct platform_device *pdev)
  789. {
  790. struct max77693_muic_info *info = platform_get_drvdata(pdev);
  791. int i;
  792. for (i = 0; i < ARRAY_SIZE(muic_irqs); i++)
  793. free_irq(muic_irqs[i].virq, info);
  794. cancel_work_sync(&info->irq_work);
  795. extcon_dev_unregister(info->edev);
  796. return 0;
  797. }
  798. static struct platform_driver max77693_muic_driver = {
  799. .driver = {
  800. .name = DEV_NAME,
  801. .owner = THIS_MODULE,
  802. },
  803. .probe = max77693_muic_probe,
  804. .remove = max77693_muic_remove,
  805. };
  806. module_platform_driver(max77693_muic_driver);
  807. MODULE_DESCRIPTION("Maxim MAX77693 Extcon driver");
  808. MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
  809. MODULE_LICENSE("GPL");
  810. MODULE_ALIAS("platform:extcon-max77693");