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