]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blame - drivers/extcon/extcon-max14577.c
extcon: max14577: Choose muic_irqs according to device type
[mirror_ubuntu-focal-kernel.git] / drivers / extcon / extcon-max14577.c
CommitLineData
962e56bf
CC
1/*
2 * extcon-max14577.c - MAX14577 extcon driver to support MAX14577 MUIC
3 *
4 * Copyright (C) 2013 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/interrupt.h>
22#include <linux/platform_device.h>
23#include <linux/mfd/max14577.h>
24#include <linux/mfd/max14577-private.h>
25#include <linux/extcon.h>
26
962e56bf
CC
27#define DELAY_MS_DEFAULT 17000 /* unit: millisecond */
28
29enum max14577_muic_adc_debounce_time {
30 ADC_DEBOUNCE_TIME_5MS = 0,
31 ADC_DEBOUNCE_TIME_10MS,
32 ADC_DEBOUNCE_TIME_25MS,
33 ADC_DEBOUNCE_TIME_38_62MS,
34};
35
36enum max14577_muic_status {
37 MAX14577_MUIC_STATUS1 = 0,
38 MAX14577_MUIC_STATUS2 = 1,
39 MAX14577_MUIC_STATUS_END,
40};
41
0ca852b7
KK
42/**
43 * struct max14577_muic_irq
44 * @irq: the index of irq list of MUIC device.
45 * @name: the name of irq.
46 * @virq: the virtual irq to use irq domain
47 */
48struct max14577_muic_irq {
49 unsigned int irq;
50 const char *name;
51 unsigned int virq;
52};
53
54static struct max14577_muic_irq max14577_muic_irqs[] = {
55 { MAX14577_IRQ_INT1_ADC, "muic-ADC" },
56 { MAX14577_IRQ_INT1_ADCLOW, "muic-ADCLOW" },
57 { MAX14577_IRQ_INT1_ADCERR, "muic-ADCError" },
58 { MAX14577_IRQ_INT2_CHGTYP, "muic-CHGTYP" },
59 { MAX14577_IRQ_INT2_CHGDETRUN, "muic-CHGDETRUN" },
60 { MAX14577_IRQ_INT2_DCDTMR, "muic-DCDTMR" },
61 { MAX14577_IRQ_INT2_DBCHG, "muic-DBCHG" },
62 { MAX14577_IRQ_INT2_VBVOLT, "muic-VBVOLT" },
63};
64
962e56bf
CC
65struct max14577_muic_info {
66 struct device *dev;
67 struct max14577 *max14577;
68 struct extcon_dev *edev;
69 int prev_cable_type;
70 int prev_chg_type;
71 u8 status[MAX14577_MUIC_STATUS_END];
72
0ca852b7
KK
73 struct max14577_muic_irq *muic_irqs;
74 unsigned int muic_irqs_num;
962e56bf
CC
75 bool irq_adc;
76 bool irq_chg;
77 struct work_struct irq_work;
78 struct mutex mutex;
79
80 /*
81 * Use delayed workqueue to detect cable state and then
82 * notify cable state to notifiee/platform through uevent.
83 * After completing the booting of platform, the extcon provider
84 * driver should notify cable state to upper layer.
85 */
86 struct delayed_work wq_detcable;
87
88 /*
89 * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB
90 * h/w path of COMP2/COMN1 on CONTROL1 register.
91 */
92 int path_usb;
93 int path_uart;
94};
95
96enum max14577_muic_cable_group {
97 MAX14577_CABLE_GROUP_ADC = 0,
98 MAX14577_CABLE_GROUP_CHG,
99};
100
962e56bf
CC
101/* Define supported accessory type */
102enum max14577_muic_acc_type {
103 MAX14577_MUIC_ADC_GROUND = 0x0,
104 MAX14577_MUIC_ADC_SEND_END_BUTTON,
105 MAX14577_MUIC_ADC_REMOTE_S1_BUTTON,
106 MAX14577_MUIC_ADC_REMOTE_S2_BUTTON,
107 MAX14577_MUIC_ADC_REMOTE_S3_BUTTON,
108 MAX14577_MUIC_ADC_REMOTE_S4_BUTTON,
109 MAX14577_MUIC_ADC_REMOTE_S5_BUTTON,
110 MAX14577_MUIC_ADC_REMOTE_S6_BUTTON,
111 MAX14577_MUIC_ADC_REMOTE_S7_BUTTON,
112 MAX14577_MUIC_ADC_REMOTE_S8_BUTTON,
113 MAX14577_MUIC_ADC_REMOTE_S9_BUTTON,
114 MAX14577_MUIC_ADC_REMOTE_S10_BUTTON,
115 MAX14577_MUIC_ADC_REMOTE_S11_BUTTON,
116 MAX14577_MUIC_ADC_REMOTE_S12_BUTTON,
117 MAX14577_MUIC_ADC_RESERVED_ACC_1,
118 MAX14577_MUIC_ADC_RESERVED_ACC_2,
119 MAX14577_MUIC_ADC_RESERVED_ACC_3,
120 MAX14577_MUIC_ADC_RESERVED_ACC_4,
121 MAX14577_MUIC_ADC_RESERVED_ACC_5,
122 MAX14577_MUIC_ADC_AUDIO_DEVICE_TYPE2,
123 MAX14577_MUIC_ADC_PHONE_POWERED_DEV,
124 MAX14577_MUIC_ADC_TTY_CONVERTER,
125 MAX14577_MUIC_ADC_UART_CABLE,
126 MAX14577_MUIC_ADC_CEA936A_TYPE1_CHG,
127 MAX14577_MUIC_ADC_FACTORY_MODE_USB_OFF,
128 MAX14577_MUIC_ADC_FACTORY_MODE_USB_ON,
129 MAX14577_MUIC_ADC_AV_CABLE_NOLOAD,
130 MAX14577_MUIC_ADC_CEA936A_TYPE2_CHG,
131 MAX14577_MUIC_ADC_FACTORY_MODE_UART_OFF,
132 MAX14577_MUIC_ADC_FACTORY_MODE_UART_ON,
133 MAX14577_MUIC_ADC_AUDIO_DEVICE_TYPE1, /* with Remote and Simple Ctrl */
134 MAX14577_MUIC_ADC_OPEN,
135};
136
137/* max14577 MUIC device support below list of accessories(external connector) */
138enum {
139 EXTCON_CABLE_USB = 0,
140 EXTCON_CABLE_TA,
141 EXTCON_CABLE_FAST_CHARGER,
142 EXTCON_CABLE_SLOW_CHARGER,
143 EXTCON_CABLE_CHARGE_DOWNSTREAM,
144 EXTCON_CABLE_JIG_USB_ON,
145 EXTCON_CABLE_JIG_USB_OFF,
146 EXTCON_CABLE_JIG_UART_OFF,
147 EXTCON_CABLE_JIG_UART_ON,
148
149 _EXTCON_CABLE_NUM,
150};
151
152static const char *max14577_extcon_cable[] = {
153 [EXTCON_CABLE_USB] = "USB",
154 [EXTCON_CABLE_TA] = "TA",
155 [EXTCON_CABLE_FAST_CHARGER] = "Fast-charger",
156 [EXTCON_CABLE_SLOW_CHARGER] = "Slow-charger",
157 [EXTCON_CABLE_CHARGE_DOWNSTREAM] = "Charge-downstream",
158 [EXTCON_CABLE_JIG_USB_ON] = "JIG-USB-ON",
159 [EXTCON_CABLE_JIG_USB_OFF] = "JIG-USB-OFF",
160 [EXTCON_CABLE_JIG_UART_OFF] = "JIG-UART-OFF",
161 [EXTCON_CABLE_JIG_UART_ON] = "JIG-UART-ON",
162
163 NULL,
164};
165
166/*
167 * max14577_muic_set_debounce_time - Set the debounce time of ADC
168 * @info: the instance including private data of max14577 MUIC
169 * @time: the debounce time of ADC
170 */
171static int max14577_muic_set_debounce_time(struct max14577_muic_info *info,
172 enum max14577_muic_adc_debounce_time time)
173{
174 u8 ret;
175
176 switch (time) {
177 case ADC_DEBOUNCE_TIME_5MS:
178 case ADC_DEBOUNCE_TIME_10MS:
179 case ADC_DEBOUNCE_TIME_25MS:
180 case ADC_DEBOUNCE_TIME_38_62MS:
181 ret = max14577_update_reg(info->max14577->regmap,
182 MAX14577_MUIC_REG_CONTROL3,
183 CTRL3_ADCDBSET_MASK,
184 time << CTRL3_ADCDBSET_SHIFT);
185 if (ret) {
186 dev_err(info->dev, "failed to set ADC debounce time\n");
187 return ret;
188 }
189 break;
190 default:
191 dev_err(info->dev, "invalid ADC debounce time\n");
192 return -EINVAL;
193 }
194
195 return 0;
196};
197
198/*
199 * max14577_muic_set_path - Set hardware line according to attached cable
200 * @info: the instance including private data of max14577 MUIC
201 * @value: the path according to attached cable
202 * @attached: the state of cable (true:attached, false:detached)
203 *
204 * The max14577 MUIC device share outside H/W line among a varity of cables
205 * so, this function set internal path of H/W line according to the type of
206 * attached cable.
207 */
208static int max14577_muic_set_path(struct max14577_muic_info *info,
209 u8 val, bool attached)
210{
211 int ret = 0;
212 u8 ctrl1, ctrl2 = 0;
213
214 /* Set open state to path before changing hw path */
215 ret = max14577_update_reg(info->max14577->regmap,
216 MAX14577_MUIC_REG_CONTROL1,
217 CLEAR_IDBEN_MICEN_MASK, CTRL1_SW_OPEN);
218 if (ret < 0) {
219 dev_err(info->dev, "failed to update MUIC register\n");
220 return ret;
221 }
222
223 if (attached)
224 ctrl1 = val;
225 else
226 ctrl1 = CTRL1_SW_OPEN;
227
228 ret = max14577_update_reg(info->max14577->regmap,
229 MAX14577_MUIC_REG_CONTROL1,
230 CLEAR_IDBEN_MICEN_MASK, ctrl1);
231 if (ret < 0) {
232 dev_err(info->dev, "failed to update MUIC register\n");
233 return ret;
234 }
235
236 if (attached)
237 ctrl2 |= CTRL2_CPEN_MASK; /* LowPwr=0, CPEn=1 */
238 else
239 ctrl2 |= CTRL2_LOWPWR_MASK; /* LowPwr=1, CPEn=0 */
240
241 ret = max14577_update_reg(info->max14577->regmap,
242 MAX14577_REG_CONTROL2,
243 CTRL2_LOWPWR_MASK | CTRL2_CPEN_MASK, ctrl2);
244 if (ret < 0) {
245 dev_err(info->dev, "failed to update MUIC register\n");
246 return ret;
247 }
248
249 dev_dbg(info->dev,
250 "CONTROL1 : 0x%02x, CONTROL2 : 0x%02x, state : %s\n",
251 ctrl1, ctrl2, attached ? "attached" : "detached");
252
253 return 0;
254}
255
256/*
257 * max14577_muic_get_cable_type - Return cable type and check cable state
258 * @info: the instance including private data of max14577 MUIC
259 * @group: the path according to attached cable
260 * @attached: store cable state and return
261 *
262 * This function check the cable state either attached or detached,
263 * and then divide precise type of cable according to cable group.
264 * - max14577_CABLE_GROUP_ADC
265 * - max14577_CABLE_GROUP_CHG
266 */
267static int max14577_muic_get_cable_type(struct max14577_muic_info *info,
268 enum max14577_muic_cable_group group, bool *attached)
269{
270 int cable_type = 0;
271 int adc;
272 int chg_type;
273
274 switch (group) {
275 case MAX14577_CABLE_GROUP_ADC:
276 /*
277 * Read ADC value to check cable type and decide cable state
278 * according to cable type
279 */
280 adc = info->status[MAX14577_MUIC_STATUS1] & STATUS1_ADC_MASK;
281 adc >>= STATUS1_ADC_SHIFT;
282
283 /*
284 * Check current cable state/cable type and store cable type
285 * (info->prev_cable_type) for handling cable when cable is
286 * detached.
287 */
288 if (adc == MAX14577_MUIC_ADC_OPEN) {
289 *attached = false;
290
291 cable_type = info->prev_cable_type;
292 info->prev_cable_type = MAX14577_MUIC_ADC_OPEN;
293 } else {
294 *attached = true;
295
296 cable_type = info->prev_cable_type = adc;
297 }
298 break;
299 case MAX14577_CABLE_GROUP_CHG:
300 /*
301 * Read charger type to check cable type and decide cable state
302 * according to type of charger cable.
303 */
304 chg_type = info->status[MAX14577_MUIC_STATUS2] &
305 STATUS2_CHGTYP_MASK;
306 chg_type >>= STATUS2_CHGTYP_SHIFT;
307
308 if (chg_type == MAX14577_CHARGER_TYPE_NONE) {
309 *attached = false;
310
311 cable_type = info->prev_chg_type;
312 info->prev_chg_type = MAX14577_CHARGER_TYPE_NONE;
313 } else {
314 *attached = true;
315
316 /*
317 * Check current cable state/cable type and store cable
318 * type(info->prev_chg_type) for handling cable when
319 * charger cable is detached.
320 */
321 cable_type = info->prev_chg_type = chg_type;
322 }
323
324 break;
325 default:
326 dev_err(info->dev, "Unknown cable group (%d)\n", group);
327 cable_type = -EINVAL;
328 break;
329 }
330
331 return cable_type;
332}
333
334static int max14577_muic_jig_handler(struct max14577_muic_info *info,
335 int cable_type, bool attached)
336{
337 char cable_name[32];
338 int ret = 0;
339 u8 path = CTRL1_SW_OPEN;
340
341 dev_dbg(info->dev,
342 "external connector is %s (adc:0x%02x)\n",
343 attached ? "attached" : "detached", cable_type);
344
345 switch (cable_type) {
346 case MAX14577_MUIC_ADC_FACTORY_MODE_USB_OFF: /* ADC_JIG_USB_OFF */
347 /* PATH:AP_USB */
348 strcpy(cable_name, "JIG-USB-OFF");
349 path = CTRL1_SW_USB;
350 break;
351 case MAX14577_MUIC_ADC_FACTORY_MODE_USB_ON: /* ADC_JIG_USB_ON */
352 /* PATH:AP_USB */
353 strcpy(cable_name, "JIG-USB-ON");
354 path = CTRL1_SW_USB;
355 break;
356 case MAX14577_MUIC_ADC_FACTORY_MODE_UART_OFF: /* ADC_JIG_UART_OFF */
357 /* PATH:AP_UART */
358 strcpy(cable_name, "JIG-UART-OFF");
359 path = CTRL1_SW_UART;
360 break;
361 default:
362 dev_err(info->dev, "failed to detect %s jig cable\n",
363 attached ? "attached" : "detached");
364 return -EINVAL;
365 }
366
367 ret = max14577_muic_set_path(info, path, attached);
368 if (ret < 0)
369 return ret;
370
371 extcon_set_cable_state(info->edev, cable_name, attached);
372
373 return 0;
374}
375
376static int max14577_muic_adc_handler(struct max14577_muic_info *info)
377{
378 int cable_type;
379 bool attached;
380 int ret = 0;
381
382 /* Check accessory state which is either detached or attached */
383 cable_type = max14577_muic_get_cable_type(info,
384 MAX14577_CABLE_GROUP_ADC, &attached);
385
386 dev_dbg(info->dev,
387 "external connector is %s (adc:0x%02x, prev_adc:0x%x)\n",
388 attached ? "attached" : "detached", cable_type,
389 info->prev_cable_type);
390
391 switch (cable_type) {
392 case MAX14577_MUIC_ADC_FACTORY_MODE_USB_OFF:
393 case MAX14577_MUIC_ADC_FACTORY_MODE_USB_ON:
394 case MAX14577_MUIC_ADC_FACTORY_MODE_UART_OFF:
395 /* JIG */
396 ret = max14577_muic_jig_handler(info, cable_type, attached);
397 if (ret < 0)
398 return ret;
399 break;
400 case MAX14577_MUIC_ADC_GROUND:
401 case MAX14577_MUIC_ADC_SEND_END_BUTTON:
402 case MAX14577_MUIC_ADC_REMOTE_S1_BUTTON:
403 case MAX14577_MUIC_ADC_REMOTE_S2_BUTTON:
404 case MAX14577_MUIC_ADC_REMOTE_S3_BUTTON:
405 case MAX14577_MUIC_ADC_REMOTE_S4_BUTTON:
406 case MAX14577_MUIC_ADC_REMOTE_S5_BUTTON:
407 case MAX14577_MUIC_ADC_REMOTE_S6_BUTTON:
408 case MAX14577_MUIC_ADC_REMOTE_S7_BUTTON:
409 case MAX14577_MUIC_ADC_REMOTE_S8_BUTTON:
410 case MAX14577_MUIC_ADC_REMOTE_S9_BUTTON:
411 case MAX14577_MUIC_ADC_REMOTE_S10_BUTTON:
412 case MAX14577_MUIC_ADC_REMOTE_S11_BUTTON:
413 case MAX14577_MUIC_ADC_REMOTE_S12_BUTTON:
414 case MAX14577_MUIC_ADC_RESERVED_ACC_1:
415 case MAX14577_MUIC_ADC_RESERVED_ACC_2:
416 case MAX14577_MUIC_ADC_RESERVED_ACC_3:
417 case MAX14577_MUIC_ADC_RESERVED_ACC_4:
418 case MAX14577_MUIC_ADC_RESERVED_ACC_5:
419 case MAX14577_MUIC_ADC_AUDIO_DEVICE_TYPE2:
420 case MAX14577_MUIC_ADC_PHONE_POWERED_DEV:
421 case MAX14577_MUIC_ADC_TTY_CONVERTER:
422 case MAX14577_MUIC_ADC_UART_CABLE:
423 case MAX14577_MUIC_ADC_CEA936A_TYPE1_CHG:
424 case MAX14577_MUIC_ADC_AV_CABLE_NOLOAD:
425 case MAX14577_MUIC_ADC_CEA936A_TYPE2_CHG:
426 case MAX14577_MUIC_ADC_FACTORY_MODE_UART_ON:
427 case MAX14577_MUIC_ADC_AUDIO_DEVICE_TYPE1:
428 /*
429 * This accessory isn't used in general case if it is specially
430 * needed to detect additional accessory, should implement
431 * proper operation when this accessory is attached/detached.
432 */
433 dev_info(info->dev,
434 "accessory is %s but it isn't used (adc:0x%x)\n",
435 attached ? "attached" : "detached", cable_type);
436 return -EAGAIN;
437 default:
438 dev_err(info->dev,
439 "failed to detect %s accessory (adc:0x%x)\n",
440 attached ? "attached" : "detached", cable_type);
441 return -EINVAL;
442 }
443
444 return 0;
445}
446
447static int max14577_muic_chg_handler(struct max14577_muic_info *info)
448{
449 int chg_type;
450 bool attached;
451 int ret = 0;
452
453 chg_type = max14577_muic_get_cable_type(info,
454 MAX14577_CABLE_GROUP_CHG, &attached);
455
456 dev_dbg(info->dev,
457 "external connector is %s(chg_type:0x%x, prev_chg_type:0x%x)\n",
458 attached ? "attached" : "detached",
459 chg_type, info->prev_chg_type);
460
461 switch (chg_type) {
462 case MAX14577_CHARGER_TYPE_USB:
463 /* PATH:AP_USB */
464 ret = max14577_muic_set_path(info, info->path_usb, attached);
465 if (ret < 0)
466 return ret;
467
468 extcon_set_cable_state(info->edev, "USB", attached);
469 break;
470 case MAX14577_CHARGER_TYPE_DEDICATED_CHG:
471 extcon_set_cable_state(info->edev, "TA", attached);
472 break;
473 case MAX14577_CHARGER_TYPE_DOWNSTREAM_PORT:
474 extcon_set_cable_state(info->edev,
475 "Charge-downstream", attached);
476 break;
477 case MAX14577_CHARGER_TYPE_SPECIAL_500MA:
478 extcon_set_cable_state(info->edev, "Slow-charger", attached);
479 break;
480 case MAX14577_CHARGER_TYPE_SPECIAL_1A:
481 extcon_set_cable_state(info->edev, "Fast-charger", attached);
482 break;
483 case MAX14577_CHARGER_TYPE_NONE:
484 case MAX14577_CHARGER_TYPE_DEAD_BATTERY:
485 break;
486 default:
487 dev_err(info->dev,
488 "failed to detect %s accessory (chg_type:0x%x)\n",
489 attached ? "attached" : "detached", chg_type);
490 return -EINVAL;
491 }
492
493 return 0;
494}
495
496static void max14577_muic_irq_work(struct work_struct *work)
497{
498 struct max14577_muic_info *info = container_of(work,
499 struct max14577_muic_info, irq_work);
500 int ret = 0;
501
502 if (!info->edev)
503 return;
504
505 mutex_lock(&info->mutex);
506
507 ret = max14577_bulk_read(info->max14577->regmap,
508 MAX14577_MUIC_REG_STATUS1, info->status, 2);
509 if (ret) {
510 dev_err(info->dev, "failed to read MUIC register\n");
511 mutex_unlock(&info->mutex);
512 return;
513 }
514
515 if (info->irq_adc) {
516 ret = max14577_muic_adc_handler(info);
517 info->irq_adc = false;
518 }
519 if (info->irq_chg) {
520 ret = max14577_muic_chg_handler(info);
521 info->irq_chg = false;
522 }
523
524 if (ret < 0)
525 dev_err(info->dev, "failed to handle MUIC interrupt\n");
526
527 mutex_unlock(&info->mutex);
528
529 return;
530}
531
532static irqreturn_t max14577_muic_irq_handler(int irq, void *data)
533{
534 struct max14577_muic_info *info = data;
535 int i, irq_type = -1;
536
537 /*
538 * We may be called multiple times for different nested IRQ-s.
539 * Including changes in INT1_ADC and INT2_CGHTYP at once.
540 * However we only need to know whether it was ADC, charger
541 * or both interrupts so decode IRQ and turn on proper flags.
542 */
0ca852b7
KK
543 for (i = 0; i < info->muic_irqs_num; i++)
544 if (irq == info->muic_irqs[i].virq)
545 irq_type = info->muic_irqs[i].irq;
962e56bf
CC
546
547 switch (irq_type) {
548 case MAX14577_IRQ_INT1_ADC:
549 case MAX14577_IRQ_INT1_ADCLOW:
550 case MAX14577_IRQ_INT1_ADCERR:
551 /* Handle all of accessory except for
552 type of charger accessory */
553 info->irq_adc = true;
554 break;
555 case MAX14577_IRQ_INT2_CHGTYP:
556 case MAX14577_IRQ_INT2_CHGDETRUN:
557 case MAX14577_IRQ_INT2_DCDTMR:
558 case MAX14577_IRQ_INT2_DBCHG:
559 case MAX14577_IRQ_INT2_VBVOLT:
560 /* Handle charger accessory */
561 info->irq_chg = true;
562 break;
563 default:
564 dev_err(info->dev, "muic interrupt: irq %d occurred, skipped\n",
565 irq_type);
566 return IRQ_HANDLED;
567 }
568 schedule_work(&info->irq_work);
569
570 return IRQ_HANDLED;
571}
572
573static int max14577_muic_detect_accessory(struct max14577_muic_info *info)
574{
575 int ret = 0;
576 int adc;
577 int chg_type;
578 bool attached;
579
580 mutex_lock(&info->mutex);
581
582 /* Read STATUSx register to detect accessory */
583 ret = max14577_bulk_read(info->max14577->regmap,
584 MAX14577_MUIC_REG_STATUS1, info->status, 2);
585 if (ret) {
586 dev_err(info->dev, "failed to read MUIC register\n");
587 mutex_unlock(&info->mutex);
588 return ret;
589 }
590
591 adc = max14577_muic_get_cable_type(info, MAX14577_CABLE_GROUP_ADC,
592 &attached);
593 if (attached && adc != MAX14577_MUIC_ADC_OPEN) {
594 ret = max14577_muic_adc_handler(info);
595 if (ret < 0) {
596 dev_err(info->dev, "Cannot detect accessory\n");
597 mutex_unlock(&info->mutex);
598 return ret;
599 }
600 }
601
602 chg_type = max14577_muic_get_cable_type(info, MAX14577_CABLE_GROUP_CHG,
603 &attached);
604 if (attached && chg_type != MAX14577_CHARGER_TYPE_NONE) {
605 ret = max14577_muic_chg_handler(info);
606 if (ret < 0) {
607 dev_err(info->dev, "Cannot detect charger accessory\n");
608 mutex_unlock(&info->mutex);
609 return ret;
610 }
611 }
612
613 mutex_unlock(&info->mutex);
614
615 return 0;
616}
617
618static void max14577_muic_detect_cable_wq(struct work_struct *work)
619{
620 struct max14577_muic_info *info = container_of(to_delayed_work(work),
621 struct max14577_muic_info, wq_detcable);
622
623 max14577_muic_detect_accessory(info);
624}
625
626static int max14577_muic_probe(struct platform_device *pdev)
627{
628 struct max14577 *max14577 = dev_get_drvdata(pdev->dev.parent);
629 struct max14577_muic_info *info;
630 int delay_jiffies;
631 int ret;
632 int i;
633 u8 id;
634
635 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
636 if (!info) {
637 dev_err(&pdev->dev, "failed to allocate memory\n");
638 return -ENOMEM;
639 }
640 info->dev = &pdev->dev;
641 info->max14577 = max14577;
642
643 platform_set_drvdata(pdev, info);
644 mutex_init(&info->mutex);
645
646 INIT_WORK(&info->irq_work, max14577_muic_irq_work);
647
0ca852b7
KK
648 switch (max14577->dev_type) {
649 case MAXIM_DEVICE_TYPE_MAX14577:
650 default:
651 info->muic_irqs = max14577_muic_irqs;
652 info->muic_irqs_num = ARRAY_SIZE(max14577_muic_irqs);
653 }
654
962e56bf 655 /* Support irq domain for max14577 MUIC device */
0ca852b7
KK
656 for (i = 0; i < info->muic_irqs_num; i++) {
657 struct max14577_muic_irq *muic_irq = &info->muic_irqs[i];
962e56bf
CC
658 unsigned int virq = 0;
659
660 virq = regmap_irq_get_virq(max14577->irq_data, muic_irq->irq);
661 if (!virq)
662 return -EINVAL;
663 muic_irq->virq = virq;
664
665 ret = devm_request_threaded_irq(&pdev->dev, virq, NULL,
666 max14577_muic_irq_handler,
667 IRQF_NO_SUSPEND,
668 muic_irq->name, info);
669 if (ret) {
670 dev_err(&pdev->dev,
671 "failed: irq request (IRQ: %d,"
672 " error :%d)\n",
673 muic_irq->irq, ret);
674 return ret;
675 }
676 }
677
678 /* Initialize extcon device */
679 info->edev = devm_kzalloc(&pdev->dev, sizeof(*info->edev), GFP_KERNEL);
680 if (!info->edev) {
681 dev_err(&pdev->dev, "failed to allocate memory for extcon\n");
682 return -ENOMEM;
683 }
4005da5c
CC
684
685 info->edev->name = dev_name(&pdev->dev);
962e56bf
CC
686 info->edev->supported_cable = max14577_extcon_cable;
687 ret = extcon_dev_register(info->edev);
688 if (ret) {
689 dev_err(&pdev->dev, "failed to register extcon device\n");
690 return ret;
691 }
692
693 /* Default h/w line path */
694 info->path_usb = CTRL1_SW_USB;
695 info->path_uart = CTRL1_SW_UART;
696 delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT);
697
698 /* Set initial path for UART */
699 max14577_muic_set_path(info, info->path_uart, true);
700
701 /* Check revision number of MUIC device*/
702 ret = max14577_read_reg(info->max14577->regmap,
703 MAX14577_REG_DEVICEID, &id);
704 if (ret < 0) {
705 dev_err(&pdev->dev, "failed to read revision number\n");
706 goto err_extcon;
707 }
708 dev_info(info->dev, "device ID : 0x%x\n", id);
709
710 /* Set ADC debounce time */
711 max14577_muic_set_debounce_time(info, ADC_DEBOUNCE_TIME_25MS);
712
713 /*
714 * Detect accessory after completing the initialization of platform
715 *
716 * - Use delayed workqueue to detect cable state and then
717 * notify cable state to notifiee/platform through uevent.
718 * After completing the booting of platform, the extcon provider
719 * driver should notify cable state to upper layer.
720 */
721 INIT_DELAYED_WORK(&info->wq_detcable, max14577_muic_detect_cable_wq);
722 ret = queue_delayed_work(system_power_efficient_wq, &info->wq_detcable,
723 delay_jiffies);
724 if (ret < 0) {
725 dev_err(&pdev->dev,
726 "failed to schedule delayed work for cable detect\n");
727 goto err_extcon;
728 }
729
730 return ret;
731
732err_extcon:
733 extcon_dev_unregister(info->edev);
734 return ret;
735}
736
737static int max14577_muic_remove(struct platform_device *pdev)
738{
739 struct max14577_muic_info *info = platform_get_drvdata(pdev);
740
741 cancel_work_sync(&info->irq_work);
742 extcon_dev_unregister(info->edev);
743
744 return 0;
745}
746
747static struct platform_driver max14577_muic_driver = {
748 .driver = {
4005da5c 749 .name = "max14577-muic",
962e56bf
CC
750 .owner = THIS_MODULE,
751 },
752 .probe = max14577_muic_probe,
753 .remove = max14577_muic_remove,
754};
755
756module_platform_driver(max14577_muic_driver);
757
758MODULE_DESCRIPTION("MAXIM 14577 Extcon driver");
759MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
760MODULE_LICENSE("GPL");
761MODULE_ALIAS("platform:extcon-max14577");