Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/extcon/extcon-max77693.c
26378 views
1
// SPDX-License-Identifier: GPL-2.0+
2
//
3
// extcon-max77693.c - MAX77693 extcon driver to support MAX77693 MUIC
4
//
5
// Copyright (C) 2012 Samsung Electrnoics
6
// Chanwoo Choi <[email protected]>
7
8
#include <linux/devm-helpers.h>
9
#include <linux/kernel.h>
10
#include <linux/module.h>
11
#include <linux/i2c.h>
12
#include <linux/slab.h>
13
#include <linux/input.h>
14
#include <linux/interrupt.h>
15
#include <linux/err.h>
16
#include <linux/platform_device.h>
17
#include <linux/mfd/max77693.h>
18
#include <linux/mfd/max77693-common.h>
19
#include <linux/mfd/max77693-private.h>
20
#include <linux/extcon-provider.h>
21
#include <linux/regmap.h>
22
#include <linux/irqdomain.h>
23
24
#define DEV_NAME "max77693-muic"
25
#define DELAY_MS_DEFAULT 20000 /* unit: millisecond */
26
27
/*
28
* Default value of MAX77693 register to bring up MUIC device.
29
* If user don't set some initial value for MUIC device through platform data,
30
* extcon-max77693 driver use 'default_init_data' to bring up base operation
31
* of MAX77693 MUIC device.
32
*/
33
static struct max77693_reg_data default_init_data[] = {
34
{
35
/* STATUS2 - [3]ChgDetRun */
36
.addr = MAX77693_MUIC_REG_STATUS2,
37
.data = MAX77693_STATUS2_CHGDETRUN_MASK,
38
}, {
39
/* INTMASK1 - Unmask [3]ADC1KM,[0]ADCM */
40
.addr = MAX77693_MUIC_REG_INTMASK1,
41
.data = INTMASK1_ADC1K_MASK
42
| INTMASK1_ADC_MASK,
43
}, {
44
/* INTMASK2 - Unmask [0]ChgTypM */
45
.addr = MAX77693_MUIC_REG_INTMASK2,
46
.data = INTMASK2_CHGTYP_MASK,
47
}, {
48
/* INTMASK3 - Mask all of interrupts */
49
.addr = MAX77693_MUIC_REG_INTMASK3,
50
.data = 0x0,
51
}, {
52
/* CDETCTRL2 */
53
.addr = MAX77693_MUIC_REG_CDETCTRL2,
54
.data = CDETCTRL2_VIDRMEN_MASK
55
| CDETCTRL2_DXOVPEN_MASK,
56
},
57
};
58
59
enum max77693_muic_adc_debounce_time {
60
ADC_DEBOUNCE_TIME_5MS = 0,
61
ADC_DEBOUNCE_TIME_10MS,
62
ADC_DEBOUNCE_TIME_25MS,
63
ADC_DEBOUNCE_TIME_38_62MS,
64
};
65
66
struct max77693_muic_info {
67
struct device *dev;
68
struct max77693_dev *max77693;
69
struct extcon_dev *edev;
70
int prev_cable_type;
71
int prev_cable_type_gnd;
72
int prev_chg_type;
73
int prev_button_type;
74
u8 status[2];
75
76
int irq;
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
/* Button of dock device */
89
struct input_dev *dock;
90
91
/*
92
* Default usb/uart path whether UART/USB or AUX_UART/AUX_USB
93
* h/w path of COMP2/COMN1 on CONTROL1 register.
94
*/
95
int path_usb;
96
int path_uart;
97
};
98
99
enum max77693_muic_cable_group {
100
MAX77693_CABLE_GROUP_ADC = 0,
101
MAX77693_CABLE_GROUP_ADC_GND,
102
MAX77693_CABLE_GROUP_CHG,
103
MAX77693_CABLE_GROUP_VBVOLT,
104
};
105
106
enum max77693_muic_charger_type {
107
MAX77693_CHARGER_TYPE_NONE = 0,
108
MAX77693_CHARGER_TYPE_USB,
109
MAX77693_CHARGER_TYPE_DOWNSTREAM_PORT,
110
MAX77693_CHARGER_TYPE_DEDICATED_CHG,
111
MAX77693_CHARGER_TYPE_APPLE_500MA,
112
MAX77693_CHARGER_TYPE_APPLE_1A_2A,
113
MAX77693_CHARGER_TYPE_DEAD_BATTERY = 7,
114
};
115
116
/**
117
* struct max77693_muic_irq
118
* @irq: the index of irq list of MUIC device.
119
* @name: the name of irq.
120
* @virq: the virtual irq to use irq domain
121
*/
122
struct max77693_muic_irq {
123
unsigned int irq;
124
const char *name;
125
unsigned int virq;
126
};
127
128
static struct max77693_muic_irq muic_irqs[] = {
129
{ MAX77693_MUIC_IRQ_INT1_ADC, "muic-ADC" },
130
{ MAX77693_MUIC_IRQ_INT1_ADC_LOW, "muic-ADCLOW" },
131
{ MAX77693_MUIC_IRQ_INT1_ADC_ERR, "muic-ADCError" },
132
{ MAX77693_MUIC_IRQ_INT1_ADC1K, "muic-ADC1K" },
133
{ MAX77693_MUIC_IRQ_INT2_CHGTYP, "muic-CHGTYP" },
134
{ MAX77693_MUIC_IRQ_INT2_CHGDETREUN, "muic-CHGDETREUN" },
135
{ MAX77693_MUIC_IRQ_INT2_DCDTMR, "muic-DCDTMR" },
136
{ MAX77693_MUIC_IRQ_INT2_DXOVP, "muic-DXOVP" },
137
{ MAX77693_MUIC_IRQ_INT2_VBVOLT, "muic-VBVOLT" },
138
{ MAX77693_MUIC_IRQ_INT2_VIDRM, "muic-VIDRM" },
139
{ MAX77693_MUIC_IRQ_INT3_EOC, "muic-EOC" },
140
{ MAX77693_MUIC_IRQ_INT3_CGMBC, "muic-CGMBC" },
141
{ MAX77693_MUIC_IRQ_INT3_OVP, "muic-OVP" },
142
{ MAX77693_MUIC_IRQ_INT3_MBCCHG_ERR, "muic-MBCCHG_ERR" },
143
{ MAX77693_MUIC_IRQ_INT3_CHG_ENABLED, "muic-CHG_ENABLED" },
144
{ MAX77693_MUIC_IRQ_INT3_BAT_DET, "muic-BAT_DET" },
145
};
146
147
/* Define supported accessory type */
148
enum max77693_muic_acc_type {
149
MAX77693_MUIC_ADC_GROUND = 0x0,
150
MAX77693_MUIC_ADC_SEND_END_BUTTON,
151
MAX77693_MUIC_ADC_REMOTE_S1_BUTTON,
152
MAX77693_MUIC_ADC_REMOTE_S2_BUTTON,
153
MAX77693_MUIC_ADC_REMOTE_S3_BUTTON,
154
MAX77693_MUIC_ADC_REMOTE_S4_BUTTON,
155
MAX77693_MUIC_ADC_REMOTE_S5_BUTTON,
156
MAX77693_MUIC_ADC_REMOTE_S6_BUTTON,
157
MAX77693_MUIC_ADC_REMOTE_S7_BUTTON,
158
MAX77693_MUIC_ADC_REMOTE_S8_BUTTON,
159
MAX77693_MUIC_ADC_REMOTE_S9_BUTTON,
160
MAX77693_MUIC_ADC_REMOTE_S10_BUTTON,
161
MAX77693_MUIC_ADC_REMOTE_S11_BUTTON,
162
MAX77693_MUIC_ADC_REMOTE_S12_BUTTON,
163
MAX77693_MUIC_ADC_RESERVED_ACC_1,
164
MAX77693_MUIC_ADC_RESERVED_ACC_2,
165
MAX77693_MUIC_ADC_RESERVED_ACC_3,
166
MAX77693_MUIC_ADC_RESERVED_ACC_4,
167
MAX77693_MUIC_ADC_RESERVED_ACC_5,
168
MAX77693_MUIC_ADC_CEA936_AUDIO,
169
MAX77693_MUIC_ADC_PHONE_POWERED_DEV,
170
MAX77693_MUIC_ADC_TTY_CONVERTER,
171
MAX77693_MUIC_ADC_UART_CABLE,
172
MAX77693_MUIC_ADC_CEA936A_TYPE1_CHG,
173
MAX77693_MUIC_ADC_FACTORY_MODE_USB_OFF,
174
MAX77693_MUIC_ADC_FACTORY_MODE_USB_ON,
175
MAX77693_MUIC_ADC_AV_CABLE_NOLOAD,
176
MAX77693_MUIC_ADC_CEA936A_TYPE2_CHG,
177
MAX77693_MUIC_ADC_FACTORY_MODE_UART_OFF,
178
MAX77693_MUIC_ADC_FACTORY_MODE_UART_ON,
179
MAX77693_MUIC_ADC_AUDIO_MODE_REMOTE,
180
MAX77693_MUIC_ADC_OPEN,
181
182
/*
183
* The below accessories have same ADC value so ADCLow and
184
* ADC1K bit is used to separate specific accessory.
185
*/
186
/* ADC|VBVolot|ADCLow|ADC1K| */
187
MAX77693_MUIC_GND_USB_HOST = 0x100, /* 0x0| 0| 0| 0| */
188
MAX77693_MUIC_GND_USB_HOST_VB = 0x104, /* 0x0| 1| 0| 0| */
189
MAX77693_MUIC_GND_AV_CABLE_LOAD = 0x102,/* 0x0| 0| 1| 0| */
190
MAX77693_MUIC_GND_MHL = 0x103, /* 0x0| 0| 1| 1| */
191
MAX77693_MUIC_GND_MHL_VB = 0x107, /* 0x0| 1| 1| 1| */
192
};
193
194
/*
195
* MAX77693 MUIC device support below list of accessories(external connector)
196
*/
197
static const unsigned int max77693_extcon_cable[] = {
198
EXTCON_USB,
199
EXTCON_USB_HOST,
200
EXTCON_CHG_USB_SDP,
201
EXTCON_CHG_USB_DCP,
202
EXTCON_CHG_USB_FAST,
203
EXTCON_CHG_USB_SLOW,
204
EXTCON_CHG_USB_CDP,
205
EXTCON_DISP_MHL,
206
EXTCON_JIG,
207
EXTCON_DOCK,
208
EXTCON_NONE,
209
};
210
211
/*
212
* max77693_muic_set_debounce_time - Set the debounce time of ADC
213
* @info: the instance including private data of max77693 MUIC
214
* @time: the debounce time of ADC
215
*/
216
static int max77693_muic_set_debounce_time(struct max77693_muic_info *info,
217
enum max77693_muic_adc_debounce_time time)
218
{
219
int ret;
220
221
switch (time) {
222
case ADC_DEBOUNCE_TIME_5MS:
223
case ADC_DEBOUNCE_TIME_10MS:
224
case ADC_DEBOUNCE_TIME_25MS:
225
case ADC_DEBOUNCE_TIME_38_62MS:
226
/*
227
* Don't touch BTLDset, JIGset when you want to change adc
228
* debounce time. If it writes other than 0 to BTLDset, JIGset
229
* muic device will be reset and loose current state.
230
*/
231
ret = regmap_write(info->max77693->regmap_muic,
232
MAX77693_MUIC_REG_CTRL3,
233
time << MAX77693_CONTROL3_ADCDBSET_SHIFT);
234
if (ret) {
235
dev_err(info->dev, "failed to set ADC debounce time\n");
236
return ret;
237
}
238
break;
239
default:
240
dev_err(info->dev, "invalid ADC debounce time\n");
241
return -EINVAL;
242
}
243
244
return 0;
245
};
246
247
/*
248
* max77693_muic_set_path - Set hardware line according to attached cable
249
* @info: the instance including private data of max77693 MUIC
250
* @value: the path according to attached cable
251
* @attached: the state of cable (true:attached, false:detached)
252
*
253
* The max77693 MUIC device share outside H/W line among a varity of cables
254
* so, this function set internal path of H/W line according to the type of
255
* attached cable.
256
*/
257
static int max77693_muic_set_path(struct max77693_muic_info *info,
258
u8 val, bool attached)
259
{
260
int ret;
261
unsigned int ctrl1, ctrl2 = 0;
262
263
if (attached)
264
ctrl1 = val;
265
else
266
ctrl1 = MAX77693_CONTROL1_SW_OPEN;
267
268
ret = regmap_update_bits(info->max77693->regmap_muic,
269
MAX77693_MUIC_REG_CTRL1, COMP_SW_MASK, ctrl1);
270
if (ret < 0) {
271
dev_err(info->dev, "failed to update MUIC register\n");
272
return ret;
273
}
274
275
if (attached)
276
ctrl2 |= MAX77693_CONTROL2_CPEN_MASK; /* LowPwr=0, CPEn=1 */
277
else
278
ctrl2 |= MAX77693_CONTROL2_LOWPWR_MASK; /* LowPwr=1, CPEn=0 */
279
280
ret = regmap_update_bits(info->max77693->regmap_muic,
281
MAX77693_MUIC_REG_CTRL2,
282
MAX77693_CONTROL2_LOWPWR_MASK | MAX77693_CONTROL2_CPEN_MASK,
283
ctrl2);
284
if (ret < 0) {
285
dev_err(info->dev, "failed to update MUIC register\n");
286
return ret;
287
}
288
289
dev_info(info->dev,
290
"CONTROL1 : 0x%02x, CONTROL2 : 0x%02x, state : %s\n",
291
ctrl1, ctrl2, attached ? "attached" : "detached");
292
293
return 0;
294
}
295
296
/*
297
* max77693_muic_get_cable_type - Return cable type and check cable state
298
* @info: the instance including private data of max77693 MUIC
299
* @group: the path according to attached cable
300
* @attached: store cable state and return
301
*
302
* This function check the cable state either attached or detached,
303
* and then divide precise type of cable according to cable group.
304
* - MAX77693_CABLE_GROUP_ADC
305
* - MAX77693_CABLE_GROUP_ADC_GND
306
* - MAX77693_CABLE_GROUP_CHG
307
* - MAX77693_CABLE_GROUP_VBVOLT
308
*/
309
static int max77693_muic_get_cable_type(struct max77693_muic_info *info,
310
enum max77693_muic_cable_group group, bool *attached)
311
{
312
int cable_type = 0;
313
int adc;
314
int adc1k;
315
int adclow;
316
int vbvolt;
317
int chg_type;
318
319
switch (group) {
320
case MAX77693_CABLE_GROUP_ADC:
321
/*
322
* Read ADC value to check cable type and decide cable state
323
* according to cable type
324
*/
325
adc = info->status[0] & MAX77693_STATUS1_ADC_MASK;
326
adc >>= MAX77693_STATUS1_ADC_SHIFT;
327
328
/*
329
* Check current cable state/cable type and store cable type
330
* (info->prev_cable_type) for handling cable when cable is
331
* detached.
332
*/
333
if (adc == MAX77693_MUIC_ADC_OPEN) {
334
*attached = false;
335
336
cable_type = info->prev_cable_type;
337
info->prev_cable_type = MAX77693_MUIC_ADC_OPEN;
338
} else {
339
*attached = true;
340
341
cable_type = info->prev_cable_type = adc;
342
}
343
break;
344
case MAX77693_CABLE_GROUP_ADC_GND:
345
/*
346
* Read ADC value to check cable type and decide cable state
347
* according to cable type
348
*/
349
adc = info->status[0] & MAX77693_STATUS1_ADC_MASK;
350
adc >>= MAX77693_STATUS1_ADC_SHIFT;
351
352
/*
353
* Check current cable state/cable type and store cable type
354
* (info->prev_cable_type/_gnd) for handling cable when cable
355
* is detached.
356
*/
357
if (adc == MAX77693_MUIC_ADC_OPEN) {
358
*attached = false;
359
360
cable_type = info->prev_cable_type_gnd;
361
info->prev_cable_type_gnd = MAX77693_MUIC_ADC_OPEN;
362
} else {
363
*attached = true;
364
365
adclow = info->status[0] & MAX77693_STATUS1_ADCLOW_MASK;
366
adclow >>= MAX77693_STATUS1_ADCLOW_SHIFT;
367
adc1k = info->status[0] & MAX77693_STATUS1_ADC1K_MASK;
368
adc1k >>= MAX77693_STATUS1_ADC1K_SHIFT;
369
370
vbvolt = info->status[1] & MAX77693_STATUS2_VBVOLT_MASK;
371
vbvolt >>= MAX77693_STATUS2_VBVOLT_SHIFT;
372
373
/**
374
* [0x1|VBVolt|ADCLow|ADC1K]
375
* [0x1| 0| 0| 0] USB_HOST
376
* [0x1| 1| 0| 0] USB_HSOT_VB
377
* [0x1| 0| 1| 0] Audio Video cable with load
378
* [0x1| 0| 1| 1] MHL without charging cable
379
* [0x1| 1| 1| 1] MHL with charging cable
380
*/
381
cable_type = ((0x1 << 8)
382
| (vbvolt << 2)
383
| (adclow << 1)
384
| adc1k);
385
386
info->prev_cable_type = adc;
387
info->prev_cable_type_gnd = cable_type;
388
}
389
390
break;
391
case MAX77693_CABLE_GROUP_CHG:
392
/*
393
* Read charger type to check cable type and decide cable state
394
* according to type of charger cable.
395
*/
396
chg_type = info->status[1] & MAX77693_STATUS2_CHGTYP_MASK;
397
chg_type >>= MAX77693_STATUS2_CHGTYP_SHIFT;
398
399
if (chg_type == MAX77693_CHARGER_TYPE_NONE) {
400
*attached = false;
401
402
cable_type = info->prev_chg_type;
403
info->prev_chg_type = MAX77693_CHARGER_TYPE_NONE;
404
} else {
405
*attached = true;
406
407
/*
408
* Check current cable state/cable type and store cable
409
* type(info->prev_chg_type) for handling cable when
410
* charger cable is detached.
411
*/
412
cable_type = info->prev_chg_type = chg_type;
413
}
414
415
break;
416
case MAX77693_CABLE_GROUP_VBVOLT:
417
/*
418
* Read ADC value to check cable type and decide cable state
419
* according to cable type
420
*/
421
adc = info->status[0] & MAX77693_STATUS1_ADC_MASK;
422
adc >>= MAX77693_STATUS1_ADC_SHIFT;
423
chg_type = info->status[1] & MAX77693_STATUS2_CHGTYP_MASK;
424
chg_type >>= MAX77693_STATUS2_CHGTYP_SHIFT;
425
426
if (adc == MAX77693_MUIC_ADC_OPEN
427
&& chg_type == MAX77693_CHARGER_TYPE_NONE)
428
*attached = false;
429
else
430
*attached = true;
431
432
/*
433
* Read vbvolt field, if vbvolt is 1,
434
* this cable is used for charging.
435
*/
436
vbvolt = info->status[1] & MAX77693_STATUS2_VBVOLT_MASK;
437
vbvolt >>= MAX77693_STATUS2_VBVOLT_SHIFT;
438
439
cable_type = vbvolt;
440
break;
441
default:
442
dev_err(info->dev, "Unknown cable group (%d)\n", group);
443
cable_type = -EINVAL;
444
break;
445
}
446
447
return cable_type;
448
}
449
450
static int max77693_muic_dock_handler(struct max77693_muic_info *info,
451
int cable_type, bool attached)
452
{
453
int ret = 0;
454
int vbvolt;
455
bool cable_attached;
456
unsigned int dock_id;
457
458
dev_info(info->dev,
459
"external connector is %s (adc:0x%02x)\n",
460
attached ? "attached" : "detached", cable_type);
461
462
switch (cable_type) {
463
case MAX77693_MUIC_ADC_RESERVED_ACC_3: /* Dock-Smart */
464
/*
465
* Check power cable whether attached or detached state.
466
* The Dock-Smart device need surely external power supply.
467
* If power cable(USB/TA) isn't connected to Dock device,
468
* user can't use Dock-Smart for desktop mode.
469
*/
470
vbvolt = max77693_muic_get_cable_type(info,
471
MAX77693_CABLE_GROUP_VBVOLT, &cable_attached);
472
if (attached && !vbvolt) {
473
dev_warn(info->dev,
474
"Cannot detect external power supply\n");
475
return 0;
476
}
477
478
/*
479
* Notify Dock/MHL state.
480
* - Dock device include three type of cable which
481
* are HDMI, USB for mouse/keyboard and micro-usb port
482
* for USB/TA cable. Dock device need always exteranl
483
* power supply(USB/TA cable through micro-usb cable). Dock
484
* device support screen output of target to separate
485
* monitor and mouse/keyboard for desktop mode.
486
*
487
* Features of 'USB/TA cable with Dock device'
488
* - Support MHL
489
* - Support external output feature of audio
490
* - Support charging through micro-usb port without data
491
* connection if TA cable is connected to target.
492
* - Support charging and data connection through micro-usb port
493
* if USB cable is connected between target and host
494
* device.
495
* - Support OTG(On-The-Go) device (Ex: Mouse/Keyboard)
496
*/
497
ret = max77693_muic_set_path(info, info->path_usb, attached);
498
if (ret < 0)
499
return ret;
500
501
extcon_set_state_sync(info->edev, EXTCON_DOCK, attached);
502
extcon_set_state_sync(info->edev, EXTCON_DISP_MHL, attached);
503
goto out;
504
case MAX77693_MUIC_ADC_AUDIO_MODE_REMOTE: /* Dock-Desk */
505
dock_id = EXTCON_DOCK;
506
break;
507
case MAX77693_MUIC_ADC_AV_CABLE_NOLOAD: /* Dock-Audio */
508
dock_id = EXTCON_DOCK;
509
if (!attached) {
510
extcon_set_state_sync(info->edev, EXTCON_USB, false);
511
extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SDP,
512
false);
513
}
514
break;
515
default:
516
dev_err(info->dev, "failed to detect %s dock device\n",
517
attached ? "attached" : "detached");
518
return -EINVAL;
519
}
520
521
/* Dock-Car/Desk/Audio, PATH:AUDIO */
522
ret = max77693_muic_set_path(info, MAX77693_CONTROL1_SW_AUDIO,
523
attached);
524
if (ret < 0)
525
return ret;
526
extcon_set_state_sync(info->edev, dock_id, attached);
527
528
out:
529
return 0;
530
}
531
532
static int max77693_muic_dock_button_handler(struct max77693_muic_info *info,
533
int button_type, bool attached)
534
{
535
struct input_dev *dock = info->dock;
536
unsigned int code;
537
538
switch (button_type) {
539
case MAX77693_MUIC_ADC_REMOTE_S3_BUTTON-1
540
... MAX77693_MUIC_ADC_REMOTE_S3_BUTTON+1:
541
/* DOCK_KEY_PREV */
542
code = KEY_PREVIOUSSONG;
543
break;
544
case MAX77693_MUIC_ADC_REMOTE_S7_BUTTON-1
545
... MAX77693_MUIC_ADC_REMOTE_S7_BUTTON+1:
546
/* DOCK_KEY_NEXT */
547
code = KEY_NEXTSONG;
548
break;
549
case MAX77693_MUIC_ADC_REMOTE_S9_BUTTON:
550
/* DOCK_VOL_DOWN */
551
code = KEY_VOLUMEDOWN;
552
break;
553
case MAX77693_MUIC_ADC_REMOTE_S10_BUTTON:
554
/* DOCK_VOL_UP */
555
code = KEY_VOLUMEUP;
556
break;
557
case MAX77693_MUIC_ADC_REMOTE_S12_BUTTON-1
558
... MAX77693_MUIC_ADC_REMOTE_S12_BUTTON+1:
559
/* DOCK_KEY_PLAY_PAUSE */
560
code = KEY_PLAYPAUSE;
561
break;
562
default:
563
dev_err(info->dev,
564
"failed to detect %s key (adc:0x%x)\n",
565
attached ? "pressed" : "released", button_type);
566
return -EINVAL;
567
}
568
569
input_event(dock, EV_KEY, code, attached);
570
input_sync(dock);
571
572
return 0;
573
}
574
575
static int max77693_muic_adc_ground_handler(struct max77693_muic_info *info)
576
{
577
int cable_type_gnd;
578
int ret = 0;
579
bool attached;
580
581
cable_type_gnd = max77693_muic_get_cable_type(info,
582
MAX77693_CABLE_GROUP_ADC_GND, &attached);
583
584
switch (cable_type_gnd) {
585
case MAX77693_MUIC_GND_USB_HOST:
586
case MAX77693_MUIC_GND_USB_HOST_VB:
587
/* USB_HOST, PATH: AP_USB */
588
ret = max77693_muic_set_path(info, MAX77693_CONTROL1_SW_USB,
589
attached);
590
if (ret < 0)
591
return ret;
592
extcon_set_state_sync(info->edev, EXTCON_USB_HOST, attached);
593
break;
594
case MAX77693_MUIC_GND_AV_CABLE_LOAD:
595
/* Audio Video Cable with load, PATH:AUDIO */
596
ret = max77693_muic_set_path(info, MAX77693_CONTROL1_SW_AUDIO,
597
attached);
598
if (ret < 0)
599
return ret;
600
extcon_set_state_sync(info->edev, EXTCON_USB, attached);
601
extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SDP,
602
attached);
603
break;
604
case MAX77693_MUIC_GND_MHL:
605
case MAX77693_MUIC_GND_MHL_VB:
606
/* MHL or MHL with USB/TA cable */
607
extcon_set_state_sync(info->edev, EXTCON_DISP_MHL, attached);
608
break;
609
default:
610
dev_err(info->dev, "failed to detect %s cable of gnd type\n",
611
attached ? "attached" : "detached");
612
return -EINVAL;
613
}
614
615
return 0;
616
}
617
618
static int max77693_muic_jig_handler(struct max77693_muic_info *info,
619
int cable_type, bool attached)
620
{
621
int ret = 0;
622
u8 path = MAX77693_CONTROL1_SW_OPEN;
623
624
dev_info(info->dev,
625
"external connector is %s (adc:0x%02x)\n",
626
attached ? "attached" : "detached", cable_type);
627
628
switch (cable_type) {
629
case MAX77693_MUIC_ADC_FACTORY_MODE_USB_OFF: /* ADC_JIG_USB_OFF */
630
case MAX77693_MUIC_ADC_FACTORY_MODE_USB_ON: /* ADC_JIG_USB_ON */
631
/* PATH:AP_USB */
632
path = MAX77693_CONTROL1_SW_USB;
633
break;
634
case MAX77693_MUIC_ADC_FACTORY_MODE_UART_OFF: /* ADC_JIG_UART_OFF */
635
case MAX77693_MUIC_ADC_FACTORY_MODE_UART_ON: /* ADC_JIG_UART_ON */
636
/* PATH:AP_UART */
637
path = MAX77693_CONTROL1_SW_UART;
638
break;
639
default:
640
dev_err(info->dev, "failed to detect %s jig cable\n",
641
attached ? "attached" : "detached");
642
return -EINVAL;
643
}
644
645
ret = max77693_muic_set_path(info, path, attached);
646
if (ret < 0)
647
return ret;
648
649
extcon_set_state_sync(info->edev, EXTCON_JIG, attached);
650
651
return 0;
652
}
653
654
static int max77693_muic_adc_handler(struct max77693_muic_info *info)
655
{
656
int cable_type;
657
int button_type;
658
bool attached;
659
int ret = 0;
660
661
/* Check accessory state which is either detached or attached */
662
cable_type = max77693_muic_get_cable_type(info,
663
MAX77693_CABLE_GROUP_ADC, &attached);
664
665
dev_info(info->dev,
666
"external connector is %s (adc:0x%02x, prev_adc:0x%x)\n",
667
attached ? "attached" : "detached", cable_type,
668
info->prev_cable_type);
669
670
switch (cable_type) {
671
case MAX77693_MUIC_ADC_GROUND:
672
/* USB_HOST/MHL/Audio */
673
max77693_muic_adc_ground_handler(info);
674
break;
675
case MAX77693_MUIC_ADC_FACTORY_MODE_USB_OFF:
676
case MAX77693_MUIC_ADC_FACTORY_MODE_USB_ON:
677
case MAX77693_MUIC_ADC_FACTORY_MODE_UART_OFF:
678
case MAX77693_MUIC_ADC_FACTORY_MODE_UART_ON:
679
/* JIG */
680
ret = max77693_muic_jig_handler(info, cable_type, attached);
681
if (ret < 0)
682
return ret;
683
break;
684
case MAX77693_MUIC_ADC_RESERVED_ACC_3: /* Dock-Smart */
685
case MAX77693_MUIC_ADC_AUDIO_MODE_REMOTE: /* Dock-Desk */
686
case MAX77693_MUIC_ADC_AV_CABLE_NOLOAD: /* Dock-Audio */
687
/*
688
* DOCK device
689
*
690
* The MAX77693 MUIC device can detect total 34 cable type
691
* except of charger cable and MUIC device didn't define
692
* specfic role of cable in the range of from 0x01 to 0x12
693
* of ADC value. So, can use/define cable with no role according
694
* to schema of hardware board.
695
*/
696
ret = max77693_muic_dock_handler(info, cable_type, attached);
697
if (ret < 0)
698
return ret;
699
break;
700
case MAX77693_MUIC_ADC_REMOTE_S3_BUTTON: /* DOCK_KEY_PREV */
701
case MAX77693_MUIC_ADC_REMOTE_S7_BUTTON: /* DOCK_KEY_NEXT */
702
case MAX77693_MUIC_ADC_REMOTE_S9_BUTTON: /* DOCK_VOL_DOWN */
703
case MAX77693_MUIC_ADC_REMOTE_S10_BUTTON: /* DOCK_VOL_UP */
704
case MAX77693_MUIC_ADC_REMOTE_S12_BUTTON: /* DOCK_KEY_PLAY_PAUSE */
705
/*
706
* Button of DOCK device
707
* - the Prev/Next/Volume Up/Volume Down/Play-Pause button
708
*
709
* The MAX77693 MUIC device can detect total 34 cable type
710
* except of charger cable and MUIC device didn't define
711
* specfic role of cable in the range of from 0x01 to 0x12
712
* of ADC value. So, can use/define cable with no role according
713
* to schema of hardware board.
714
*/
715
if (attached)
716
button_type = info->prev_button_type = cable_type;
717
else
718
button_type = info->prev_button_type;
719
720
ret = max77693_muic_dock_button_handler(info, button_type,
721
attached);
722
if (ret < 0)
723
return ret;
724
break;
725
case MAX77693_MUIC_ADC_SEND_END_BUTTON:
726
case MAX77693_MUIC_ADC_REMOTE_S1_BUTTON:
727
case MAX77693_MUIC_ADC_REMOTE_S2_BUTTON:
728
case MAX77693_MUIC_ADC_REMOTE_S4_BUTTON:
729
case MAX77693_MUIC_ADC_REMOTE_S5_BUTTON:
730
case MAX77693_MUIC_ADC_REMOTE_S6_BUTTON:
731
case MAX77693_MUIC_ADC_REMOTE_S8_BUTTON:
732
case MAX77693_MUIC_ADC_REMOTE_S11_BUTTON:
733
case MAX77693_MUIC_ADC_RESERVED_ACC_1:
734
case MAX77693_MUIC_ADC_RESERVED_ACC_2:
735
case MAX77693_MUIC_ADC_RESERVED_ACC_4:
736
case MAX77693_MUIC_ADC_RESERVED_ACC_5:
737
case MAX77693_MUIC_ADC_CEA936_AUDIO:
738
case MAX77693_MUIC_ADC_PHONE_POWERED_DEV:
739
case MAX77693_MUIC_ADC_TTY_CONVERTER:
740
case MAX77693_MUIC_ADC_UART_CABLE:
741
case MAX77693_MUIC_ADC_CEA936A_TYPE1_CHG:
742
case MAX77693_MUIC_ADC_CEA936A_TYPE2_CHG:
743
/*
744
* This accessory isn't used in general case if it is specially
745
* needed to detect additional accessory, should implement
746
* proper operation when this accessory is attached/detached.
747
*/
748
dev_info(info->dev,
749
"accessory is %s but it isn't used (adc:0x%x)\n",
750
attached ? "attached" : "detached", cable_type);
751
return -EAGAIN;
752
default:
753
dev_err(info->dev,
754
"failed to detect %s accessory (adc:0x%x)\n",
755
attached ? "attached" : "detached", cable_type);
756
return -EINVAL;
757
}
758
759
return 0;
760
}
761
762
static int max77693_muic_chg_handler(struct max77693_muic_info *info)
763
{
764
int chg_type;
765
int cable_type_gnd;
766
int cable_type;
767
bool attached;
768
bool cable_attached;
769
int ret = 0;
770
771
chg_type = max77693_muic_get_cable_type(info,
772
MAX77693_CABLE_GROUP_CHG, &attached);
773
774
dev_info(info->dev,
775
"external connector is %s(chg_type:0x%x, prev_chg_type:0x%x)\n",
776
attached ? "attached" : "detached",
777
chg_type, info->prev_chg_type);
778
779
switch (chg_type) {
780
case MAX77693_CHARGER_TYPE_USB:
781
case MAX77693_CHARGER_TYPE_DEDICATED_CHG:
782
case MAX77693_CHARGER_TYPE_NONE:
783
/* Check MAX77693_CABLE_GROUP_ADC_GND type */
784
cable_type_gnd = max77693_muic_get_cable_type(info,
785
MAX77693_CABLE_GROUP_ADC_GND,
786
&cable_attached);
787
switch (cable_type_gnd) {
788
case MAX77693_MUIC_GND_MHL:
789
case MAX77693_MUIC_GND_MHL_VB:
790
/*
791
* MHL cable with USB/TA cable
792
* - MHL cable include two port(HDMI line and separate
793
* micro-usb port. When the target connect MHL cable,
794
* extcon driver check whether USB/TA cable is
795
* connected. If USB/TA cable is connected, extcon
796
* driver notify state to notifiee for charging battery.
797
*
798
* Features of 'USB/TA with MHL cable'
799
* - Support MHL
800
* - Support charging through micro-usb port without
801
* data connection
802
*/
803
extcon_set_state_sync(info->edev, EXTCON_CHG_USB_DCP,
804
attached);
805
extcon_set_state_sync(info->edev, EXTCON_DISP_MHL,
806
cable_attached);
807
break;
808
}
809
810
/* Check MAX77693_CABLE_GROUP_ADC type */
811
cable_type = max77693_muic_get_cable_type(info,
812
MAX77693_CABLE_GROUP_ADC,
813
&cable_attached);
814
switch (cable_type) {
815
case MAX77693_MUIC_ADC_AV_CABLE_NOLOAD: /* Dock-Audio */
816
/*
817
* Dock-Audio device with USB/TA cable
818
* - Dock device include two port(Dock-Audio and micro-
819
* usb port). When the target connect Dock-Audio device,
820
* extcon driver check whether USB/TA cable is connected
821
* or not. If USB/TA cable is connected, extcon driver
822
* notify state to notifiee for charging battery.
823
*
824
* Features of 'USB/TA cable with Dock-Audio device'
825
* - Support external output feature of audio.
826
* - Support charging through micro-usb port without
827
* data connection.
828
*/
829
extcon_set_state_sync(info->edev, EXTCON_USB,
830
attached);
831
extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SDP,
832
attached);
833
834
if (!cable_attached)
835
extcon_set_state_sync(info->edev, EXTCON_DOCK,
836
cable_attached);
837
break;
838
case MAX77693_MUIC_ADC_RESERVED_ACC_3: /* Dock-Smart */
839
/*
840
* Dock-Smart device with USB/TA cable
841
* - Dock-Desk device include three type of cable which
842
* are HDMI, USB for mouse/keyboard and micro-usb port
843
* for USB/TA cable. Dock-Smart device need always
844
* exteranl power supply(USB/TA cable through micro-usb
845
* cable). Dock-Smart device support screen output of
846
* target to separate monitor and mouse/keyboard for
847
* desktop mode.
848
*
849
* Features of 'USB/TA cable with Dock-Smart device'
850
* - Support MHL
851
* - Support external output feature of audio
852
* - Support charging through micro-usb port without
853
* data connection if TA cable is connected to target.
854
* - Support charging and data connection through micro-
855
* usb port if USB cable is connected between target
856
* and host device
857
* - Support OTG(On-The-Go) device (Ex: Mouse/Keyboard)
858
*/
859
ret = max77693_muic_set_path(info, info->path_usb,
860
attached);
861
if (ret < 0)
862
return ret;
863
864
extcon_set_state_sync(info->edev, EXTCON_DOCK,
865
attached);
866
extcon_set_state_sync(info->edev, EXTCON_DISP_MHL,
867
attached);
868
break;
869
}
870
871
/* Check MAX77693_CABLE_GROUP_CHG type */
872
switch (chg_type) {
873
case MAX77693_CHARGER_TYPE_NONE:
874
/*
875
* When MHL(with USB/TA cable) or Dock-Audio with USB/TA
876
* cable is attached, muic device happen below two irq.
877
* - 'MAX77693_MUIC_IRQ_INT1_ADC' for detecting
878
* MHL/Dock-Audio.
879
* - 'MAX77693_MUIC_IRQ_INT2_CHGTYP' for detecting
880
* USB/TA cable connected to MHL or Dock-Audio.
881
* Always, happen eariler MAX77693_MUIC_IRQ_INT1_ADC
882
* irq than MAX77693_MUIC_IRQ_INT2_CHGTYP irq.
883
*
884
* If user attach MHL (with USB/TA cable and immediately
885
* detach MHL with USB/TA cable before MAX77693_MUIC_IRQ
886
* _INT2_CHGTYP irq is happened, USB/TA cable remain
887
* connected state to target. But USB/TA cable isn't
888
* connected to target. The user be face with unusual
889
* action. So, driver should check this situation in
890
* spite of, that previous charger type is N/A.
891
*/
892
break;
893
case MAX77693_CHARGER_TYPE_USB:
894
/* Only USB cable, PATH:AP_USB */
895
ret = max77693_muic_set_path(info, info->path_usb,
896
attached);
897
if (ret < 0)
898
return ret;
899
900
extcon_set_state_sync(info->edev, EXTCON_USB,
901
attached);
902
extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SDP,
903
attached);
904
break;
905
case MAX77693_CHARGER_TYPE_DEDICATED_CHG:
906
/* Only TA cable */
907
extcon_set_state_sync(info->edev, EXTCON_CHG_USB_DCP,
908
attached);
909
break;
910
}
911
break;
912
case MAX77693_CHARGER_TYPE_DOWNSTREAM_PORT:
913
extcon_set_state_sync(info->edev, EXTCON_CHG_USB_CDP,
914
attached);
915
break;
916
case MAX77693_CHARGER_TYPE_APPLE_500MA:
917
extcon_set_state_sync(info->edev, EXTCON_CHG_USB_SLOW,
918
attached);
919
break;
920
case MAX77693_CHARGER_TYPE_APPLE_1A_2A:
921
extcon_set_state_sync(info->edev, EXTCON_CHG_USB_FAST,
922
attached);
923
break;
924
case MAX77693_CHARGER_TYPE_DEAD_BATTERY:
925
break;
926
default:
927
dev_err(info->dev,
928
"failed to detect %s accessory (chg_type:0x%x)\n",
929
attached ? "attached" : "detached", chg_type);
930
return -EINVAL;
931
}
932
933
return 0;
934
}
935
936
static void max77693_muic_irq_work(struct work_struct *work)
937
{
938
struct max77693_muic_info *info = container_of(work,
939
struct max77693_muic_info, irq_work);
940
int irq_type = -1;
941
int i, ret = 0;
942
943
if (!info->edev)
944
return;
945
946
mutex_lock(&info->mutex);
947
948
for (i = 0; i < ARRAY_SIZE(muic_irqs); i++)
949
if (info->irq == muic_irqs[i].virq)
950
irq_type = muic_irqs[i].irq;
951
952
ret = regmap_bulk_read(info->max77693->regmap_muic,
953
MAX77693_MUIC_REG_STATUS1, info->status, 2);
954
if (ret) {
955
dev_err(info->dev, "failed to read MUIC register\n");
956
mutex_unlock(&info->mutex);
957
return;
958
}
959
960
switch (irq_type) {
961
case MAX77693_MUIC_IRQ_INT1_ADC:
962
case MAX77693_MUIC_IRQ_INT1_ADC_LOW:
963
case MAX77693_MUIC_IRQ_INT1_ADC_ERR:
964
case MAX77693_MUIC_IRQ_INT1_ADC1K:
965
/*
966
* Handle all of accessory except for
967
* type of charger accessory.
968
*/
969
ret = max77693_muic_adc_handler(info);
970
break;
971
case MAX77693_MUIC_IRQ_INT2_CHGTYP:
972
case MAX77693_MUIC_IRQ_INT2_CHGDETREUN:
973
case MAX77693_MUIC_IRQ_INT2_DCDTMR:
974
case MAX77693_MUIC_IRQ_INT2_DXOVP:
975
case MAX77693_MUIC_IRQ_INT2_VBVOLT:
976
case MAX77693_MUIC_IRQ_INT2_VIDRM:
977
/* Handle charger accessory */
978
ret = max77693_muic_chg_handler(info);
979
break;
980
case MAX77693_MUIC_IRQ_INT3_EOC:
981
case MAX77693_MUIC_IRQ_INT3_CGMBC:
982
case MAX77693_MUIC_IRQ_INT3_OVP:
983
case MAX77693_MUIC_IRQ_INT3_MBCCHG_ERR:
984
case MAX77693_MUIC_IRQ_INT3_CHG_ENABLED:
985
case MAX77693_MUIC_IRQ_INT3_BAT_DET:
986
break;
987
default:
988
dev_err(info->dev, "muic interrupt: irq %d occurred\n",
989
irq_type);
990
mutex_unlock(&info->mutex);
991
return;
992
}
993
994
if (ret < 0)
995
dev_err(info->dev, "failed to handle MUIC interrupt\n");
996
997
mutex_unlock(&info->mutex);
998
}
999
1000
static irqreturn_t max77693_muic_irq_handler(int irq, void *data)
1001
{
1002
struct max77693_muic_info *info = data;
1003
1004
info->irq = irq;
1005
schedule_work(&info->irq_work);
1006
1007
return IRQ_HANDLED;
1008
}
1009
1010
static const struct regmap_config max77693_muic_regmap_config = {
1011
.reg_bits = 8,
1012
.val_bits = 8,
1013
};
1014
1015
static int max77693_muic_detect_accessory(struct max77693_muic_info *info)
1016
{
1017
int ret = 0;
1018
int adc;
1019
int chg_type;
1020
bool attached;
1021
1022
mutex_lock(&info->mutex);
1023
1024
/* Read STATUSx register to detect accessory */
1025
ret = regmap_bulk_read(info->max77693->regmap_muic,
1026
MAX77693_MUIC_REG_STATUS1, info->status, 2);
1027
if (ret) {
1028
dev_err(info->dev, "failed to read MUIC register\n");
1029
mutex_unlock(&info->mutex);
1030
return ret;
1031
}
1032
1033
adc = max77693_muic_get_cable_type(info, MAX77693_CABLE_GROUP_ADC,
1034
&attached);
1035
if (attached && adc != MAX77693_MUIC_ADC_OPEN) {
1036
ret = max77693_muic_adc_handler(info);
1037
if (ret < 0) {
1038
dev_err(info->dev, "Cannot detect accessory\n");
1039
mutex_unlock(&info->mutex);
1040
return ret;
1041
}
1042
}
1043
1044
chg_type = max77693_muic_get_cable_type(info, MAX77693_CABLE_GROUP_CHG,
1045
&attached);
1046
if (attached && chg_type != MAX77693_CHARGER_TYPE_NONE) {
1047
ret = max77693_muic_chg_handler(info);
1048
if (ret < 0) {
1049
dev_err(info->dev, "Cannot detect charger accessory\n");
1050
mutex_unlock(&info->mutex);
1051
return ret;
1052
}
1053
}
1054
1055
mutex_unlock(&info->mutex);
1056
1057
return 0;
1058
}
1059
1060
static void max77693_muic_detect_cable_wq(struct work_struct *work)
1061
{
1062
struct max77693_muic_info *info = container_of(to_delayed_work(work),
1063
struct max77693_muic_info, wq_detcable);
1064
1065
max77693_muic_detect_accessory(info);
1066
}
1067
1068
static int max77693_muic_probe(struct platform_device *pdev)
1069
{
1070
struct max77693_dev *max77693 = dev_get_drvdata(pdev->dev.parent);
1071
struct max77693_platform_data *pdata = dev_get_platdata(max77693->dev);
1072
struct max77693_muic_info *info;
1073
struct max77693_reg_data *init_data;
1074
int num_init_data;
1075
int delay_jiffies;
1076
int cable_type;
1077
bool attached;
1078
int ret;
1079
int i;
1080
unsigned int id;
1081
1082
info = devm_kzalloc(&pdev->dev, sizeof(struct max77693_muic_info),
1083
GFP_KERNEL);
1084
if (!info)
1085
return -ENOMEM;
1086
1087
info->dev = &pdev->dev;
1088
info->max77693 = max77693;
1089
if (info->max77693->regmap_muic) {
1090
dev_dbg(&pdev->dev, "allocate register map\n");
1091
} else {
1092
info->max77693->regmap_muic = devm_regmap_init_i2c(
1093
info->max77693->i2c_muic,
1094
&max77693_muic_regmap_config);
1095
if (IS_ERR(info->max77693->regmap_muic)) {
1096
ret = PTR_ERR(info->max77693->regmap_muic);
1097
dev_err(max77693->dev,
1098
"failed to allocate register map: %d\n", ret);
1099
return ret;
1100
}
1101
}
1102
1103
/* Register input device for button of dock device */
1104
info->dock = devm_input_allocate_device(&pdev->dev);
1105
if (!info->dock) {
1106
dev_err(&pdev->dev, "%s: failed to allocate input\n", __func__);
1107
return -ENOMEM;
1108
}
1109
info->dock->name = "max77693-muic/dock";
1110
info->dock->phys = "max77693-muic/extcon";
1111
info->dock->dev.parent = &pdev->dev;
1112
1113
__set_bit(EV_REP, info->dock->evbit);
1114
1115
input_set_capability(info->dock, EV_KEY, KEY_VOLUMEUP);
1116
input_set_capability(info->dock, EV_KEY, KEY_VOLUMEDOWN);
1117
input_set_capability(info->dock, EV_KEY, KEY_PLAYPAUSE);
1118
input_set_capability(info->dock, EV_KEY, KEY_PREVIOUSSONG);
1119
input_set_capability(info->dock, EV_KEY, KEY_NEXTSONG);
1120
1121
ret = input_register_device(info->dock);
1122
if (ret < 0) {
1123
dev_err(&pdev->dev, "Cannot register input device error(%d)\n",
1124
ret);
1125
return ret;
1126
}
1127
1128
platform_set_drvdata(pdev, info);
1129
mutex_init(&info->mutex);
1130
1131
ret = devm_work_autocancel(&pdev->dev, &info->irq_work,
1132
max77693_muic_irq_work);
1133
if (ret)
1134
return ret;
1135
1136
/* Support irq domain for MAX77693 MUIC device */
1137
for (i = 0; i < ARRAY_SIZE(muic_irqs); i++) {
1138
struct max77693_muic_irq *muic_irq = &muic_irqs[i];
1139
int virq;
1140
1141
virq = regmap_irq_get_virq(max77693->irq_data_muic,
1142
muic_irq->irq);
1143
if (virq <= 0)
1144
return -EINVAL;
1145
muic_irq->virq = virq;
1146
1147
ret = devm_request_threaded_irq(&pdev->dev, virq, NULL,
1148
max77693_muic_irq_handler,
1149
IRQF_NO_SUSPEND,
1150
muic_irq->name, info);
1151
if (ret) {
1152
dev_err(&pdev->dev,
1153
"failed: irq request (IRQ: %d, error :%d)\n",
1154
muic_irq->irq, ret);
1155
return ret;
1156
}
1157
}
1158
1159
/* Initialize extcon device */
1160
info->edev = devm_extcon_dev_allocate(&pdev->dev,
1161
max77693_extcon_cable);
1162
if (IS_ERR(info->edev)) {
1163
dev_err(&pdev->dev, "failed to allocate memory for extcon\n");
1164
return PTR_ERR(info->edev);
1165
}
1166
1167
ret = devm_extcon_dev_register(&pdev->dev, info->edev);
1168
if (ret) {
1169
dev_err(&pdev->dev, "failed to register extcon device\n");
1170
return ret;
1171
}
1172
1173
/* Initialize MUIC register by using platform data or default data */
1174
if (pdata && pdata->muic_data) {
1175
init_data = pdata->muic_data->init_data;
1176
num_init_data = pdata->muic_data->num_init_data;
1177
} else {
1178
init_data = default_init_data;
1179
num_init_data = ARRAY_SIZE(default_init_data);
1180
}
1181
1182
for (i = 0; i < num_init_data; i++) {
1183
regmap_write(info->max77693->regmap_muic,
1184
init_data[i].addr,
1185
init_data[i].data);
1186
}
1187
1188
if (pdata && pdata->muic_data) {
1189
struct max77693_muic_platform_data *muic_pdata
1190
= pdata->muic_data;
1191
1192
/*
1193
* Default usb/uart path whether UART/USB or AUX_UART/AUX_USB
1194
* h/w path of COMP2/COMN1 on CONTROL1 register.
1195
*/
1196
if (muic_pdata->path_uart)
1197
info->path_uart = muic_pdata->path_uart;
1198
else
1199
info->path_uart = MAX77693_CONTROL1_SW_UART;
1200
1201
if (muic_pdata->path_usb)
1202
info->path_usb = muic_pdata->path_usb;
1203
else
1204
info->path_usb = MAX77693_CONTROL1_SW_USB;
1205
1206
/*
1207
* Default delay time for detecting cable state
1208
* after certain time.
1209
*/
1210
if (muic_pdata->detcable_delay_ms)
1211
delay_jiffies =
1212
msecs_to_jiffies(muic_pdata->detcable_delay_ms);
1213
else
1214
delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT);
1215
} else {
1216
info->path_usb = MAX77693_CONTROL1_SW_USB;
1217
info->path_uart = MAX77693_CONTROL1_SW_UART;
1218
delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT);
1219
}
1220
1221
/* Set initial path for UART when JIG is connected to get serial logs */
1222
ret = regmap_bulk_read(info->max77693->regmap_muic,
1223
MAX77693_MUIC_REG_STATUS1, info->status, 2);
1224
if (ret) {
1225
dev_err(info->dev, "failed to read MUIC register\n");
1226
return ret;
1227
}
1228
cable_type = max77693_muic_get_cable_type(info,
1229
MAX77693_CABLE_GROUP_ADC, &attached);
1230
if (attached && (cable_type == MAX77693_MUIC_ADC_FACTORY_MODE_UART_ON ||
1231
cable_type == MAX77693_MUIC_ADC_FACTORY_MODE_UART_OFF))
1232
max77693_muic_set_path(info, info->path_uart, true);
1233
1234
/* Check revision number of MUIC device*/
1235
ret = regmap_read(info->max77693->regmap_muic,
1236
MAX77693_MUIC_REG_ID, &id);
1237
if (ret < 0) {
1238
dev_err(&pdev->dev, "failed to read revision number\n");
1239
return ret;
1240
}
1241
dev_info(info->dev, "device ID : 0x%x\n", id);
1242
1243
/* Set ADC debounce time */
1244
max77693_muic_set_debounce_time(info, ADC_DEBOUNCE_TIME_25MS);
1245
1246
/*
1247
* Detect accessory after completing the initialization of platform
1248
*
1249
* - Use delayed workqueue to detect cable state and then
1250
* notify cable state to notifiee/platform through uevent.
1251
* After completing the booting of platform, the extcon provider
1252
* driver should notify cable state to upper layer.
1253
*/
1254
INIT_DELAYED_WORK(&info->wq_detcable, max77693_muic_detect_cable_wq);
1255
queue_delayed_work(system_power_efficient_wq, &info->wq_detcable,
1256
delay_jiffies);
1257
1258
return ret;
1259
}
1260
1261
static const struct of_device_id of_max77693_muic_dt_match[] = {
1262
{ .compatible = "maxim,max77693-muic", },
1263
{ /* sentinel */ },
1264
};
1265
MODULE_DEVICE_TABLE(of, of_max77693_muic_dt_match);
1266
1267
static struct platform_driver max77693_muic_driver = {
1268
.driver = {
1269
.name = DEV_NAME,
1270
.of_match_table = of_max77693_muic_dt_match,
1271
},
1272
.probe = max77693_muic_probe,
1273
};
1274
1275
module_platform_driver(max77693_muic_driver);
1276
1277
MODULE_DESCRIPTION("Maxim MAX77693 Extcon driver");
1278
MODULE_AUTHOR("Chanwoo Choi <[email protected]>");
1279
MODULE_LICENSE("GPL");
1280
MODULE_ALIAS("platform:max77693-muic");
1281
1282