extcon-rt8973a.c (c3b5d3cea508d2c8ff493ef18c45a9cc58fb7015) extcon-rt8973a.c (2a9de9c0f08d61fbe3764a21d22d0b72df97d6ae)
1/*
2 * extcon-rt8973a.c - Richtek RT8973A extcon driver to support USB switches
3 *
4 * Copyright (c) 2014 Samsung Electronics Co., Ltd
5 * Author: Chanwoo Choi <cw00.choi@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the

--- 76 unchanged lines hidden (view full) ---

85 | RT8973A_REG_CONTROL1_USB_CHD_EN_MASK
86 | RT8973A_REG_CONTROL1_CHGTYP_MASK,
87 .invert = false,
88 },
89 { /* sentinel */ }
90};
91
92/* List of detectable cables */
1/*
2 * extcon-rt8973a.c - Richtek RT8973A extcon driver to support USB switches
3 *
4 * Copyright (c) 2014 Samsung Electronics Co., Ltd
5 * Author: Chanwoo Choi <cw00.choi@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the

--- 76 unchanged lines hidden (view full) ---

85 | RT8973A_REG_CONTROL1_USB_CHD_EN_MASK
86 | RT8973A_REG_CONTROL1_CHGTYP_MASK,
87 .invert = false,
88 },
89 { /* sentinel */ }
90};
91
92/* List of detectable cables */
93enum {
94 EXTCON_CABLE_USB = 0,
95 EXTCON_CABLE_USB_HOST,
96 EXTCON_CABLE_TA,
97 EXTCON_CABLE_JIG_OFF_USB,
98 EXTCON_CABLE_JIG_ON_USB,
99 EXTCON_CABLE_JIG_OFF_UART,
100 EXTCON_CABLE_JIG_ON_UART,
101
102 EXTCON_CABLE_END,
93static const enum extcon rt8973a_extcon_cable[] = {
94 EXTCON_USB,
95 EXTCON_USB_HOST,
96 EXTCON_TA,
97 EXTCON_JIG,
98 EXTCON_NONE,
103};
104
99};
100
105static const char *rt8973a_extcon_cable[] = {
106 [EXTCON_CABLE_USB] = "USB",
107 [EXTCON_CABLE_USB_HOST] = "USB-Host",
108 [EXTCON_CABLE_TA] = "TA",
109 [EXTCON_CABLE_JIG_OFF_USB] = "JIG-USB-OFF",
110 [EXTCON_CABLE_JIG_ON_USB] = "JIG-USB-ON",
111 [EXTCON_CABLE_JIG_OFF_UART] = "JIG-UART-OFF",
112 [EXTCON_CABLE_JIG_ON_UART] = "JIG-UART-ON",
113 NULL,
114};
115
116/* Define OVP (Over Voltage Protection), OTP (Over Temperature Protection) */
117enum rt8973a_event_type {
118 RT8973A_EVENT_ATTACH = 1,
119 RT8973A_EVENT_DETACH,
120 RT8973A_EVENT_OVP,
121 RT8973A_EVENT_OTP,
122};
123

--- 184 unchanged lines hidden (view full) ---

308
309 return cable_type;
310}
311
312static int rt8973a_muic_cable_handler(struct rt8973a_muic_info *info,
313 enum rt8973a_event_type event)
314{
315 static unsigned int prev_cable_type;
101/* Define OVP (Over Voltage Protection), OTP (Over Temperature Protection) */
102enum rt8973a_event_type {
103 RT8973A_EVENT_ATTACH = 1,
104 RT8973A_EVENT_DETACH,
105 RT8973A_EVENT_OVP,
106 RT8973A_EVENT_OTP,
107};
108

--- 184 unchanged lines hidden (view full) ---

293
294 return cable_type;
295}
296
297static int rt8973a_muic_cable_handler(struct rt8973a_muic_info *info,
298 enum rt8973a_event_type event)
299{
300 static unsigned int prev_cable_type;
316 const char **cable_names = info->edev->supported_cable;
317 unsigned int con_sw = DM_DP_SWITCH_UART;
301 unsigned int con_sw = DM_DP_SWITCH_UART;
318 int ret, idx = 0, cable_type;
302 int ret, cable_type;
303 enum extcon id;
319 bool attached = false;
320
304 bool attached = false;
305
321 if (!cable_names)
322 return 0;
323
324 switch (event) {
325 case RT8973A_EVENT_ATTACH:
326 cable_type = rt8973a_muic_get_cable_type(info);
327 attached = true;
328 break;
329 case RT8973A_EVENT_DETACH:
330 cable_type = prev_cable_type;
331 attached = false;

--- 10 unchanged lines hidden (view full) ---

342 dev_err(info->dev,
343 "Cannot handle this event (event:%d)\n", event);
344 return -EINVAL;
345 }
346 prev_cable_type = cable_type;
347
348 switch (cable_type) {
349 case RT8973A_MUIC_ADC_OTG:
306 switch (event) {
307 case RT8973A_EVENT_ATTACH:
308 cable_type = rt8973a_muic_get_cable_type(info);
309 attached = true;
310 break;
311 case RT8973A_EVENT_DETACH:
312 cable_type = prev_cable_type;
313 attached = false;

--- 10 unchanged lines hidden (view full) ---

324 dev_err(info->dev,
325 "Cannot handle this event (event:%d)\n", event);
326 return -EINVAL;
327 }
328 prev_cable_type = cable_type;
329
330 switch (cable_type) {
331 case RT8973A_MUIC_ADC_OTG:
350 idx = EXTCON_CABLE_USB_HOST;
332 id = EXTCON_USB_HOST;
351 con_sw = DM_DP_SWITCH_USB;
352 break;
353 case RT8973A_MUIC_ADC_TA:
333 con_sw = DM_DP_SWITCH_USB;
334 break;
335 case RT8973A_MUIC_ADC_TA:
354 idx = EXTCON_CABLE_TA;
336 id = EXTCON_TA;
355 con_sw = DM_DP_SWITCH_OPEN;
356 break;
357 case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_OFF_USB:
337 con_sw = DM_DP_SWITCH_OPEN;
338 break;
339 case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_OFF_USB:
358 idx = EXTCON_CABLE_JIG_OFF_USB;
359 con_sw = DM_DP_SWITCH_UART;
360 break;
361 case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_ON_USB:
340 case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_ON_USB:
362 idx = EXTCON_CABLE_JIG_ON_USB;
363 con_sw = DM_DP_SWITCH_UART;
341 id = EXTCON_JIG;
342 con_sw = DM_DP_SWITCH_USB;
364 break;
365 case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_OFF_UART:
343 break;
344 case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_OFF_UART:
366 idx = EXTCON_CABLE_JIG_OFF_UART;
367 con_sw = DM_DP_SWITCH_UART;
368 break;
369 case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_ON_UART:
345 case RT8973A_MUIC_ADC_FACTORY_MODE_BOOT_ON_UART:
370 idx = EXTCON_CABLE_JIG_ON_UART;
346 id = EXTCON_JIG;
371 con_sw = DM_DP_SWITCH_UART;
372 break;
373 case RT8973A_MUIC_ADC_USB:
347 con_sw = DM_DP_SWITCH_UART;
348 break;
349 case RT8973A_MUIC_ADC_USB:
374 idx = EXTCON_CABLE_USB;
350 id = EXTCON_USB;
375 con_sw = DM_DP_SWITCH_USB;
376 break;
377 case RT8973A_MUIC_ADC_OPEN:
378 return 0;
379 case RT8973A_MUIC_ADC_UNKNOWN_ACC_1:
380 case RT8973A_MUIC_ADC_UNKNOWN_ACC_2:
381 case RT8973A_MUIC_ADC_UNKNOWN_ACC_3:
382 case RT8973A_MUIC_ADC_UNKNOWN_ACC_4:

--- 33 unchanged lines hidden (view full) ---

416 }
417
418 /* Change internal hardware path(DM_CON/DP_CON) */
419 ret = rt8973a_muic_set_path(info, con_sw, attached);
420 if (ret < 0)
421 return ret;
422
423 /* Change the state of external accessory */
351 con_sw = DM_DP_SWITCH_USB;
352 break;
353 case RT8973A_MUIC_ADC_OPEN:
354 return 0;
355 case RT8973A_MUIC_ADC_UNKNOWN_ACC_1:
356 case RT8973A_MUIC_ADC_UNKNOWN_ACC_2:
357 case RT8973A_MUIC_ADC_UNKNOWN_ACC_3:
358 case RT8973A_MUIC_ADC_UNKNOWN_ACC_4:

--- 33 unchanged lines hidden (view full) ---

392 }
393
394 /* Change internal hardware path(DM_CON/DP_CON) */
395 ret = rt8973a_muic_set_path(info, con_sw, attached);
396 if (ret < 0)
397 return ret;
398
399 /* Change the state of external accessory */
424 extcon_set_cable_state(info->edev, cable_names[idx], attached);
400 extcon_set_cable_state_(info->edev, id, attached);
425
426 return 0;
427}
428
429static void rt8973a_muic_irq_work(struct work_struct *work)
430{
431 struct rt8973a_muic_info *info = container_of(work,
432 struct rt8973a_muic_info, irq_work);

--- 205 unchanged lines hidden (view full) ---

638 }
639
640 /* Allocate extcon device */
641 info->edev = devm_extcon_dev_allocate(info->dev, rt8973a_extcon_cable);
642 if (IS_ERR(info->edev)) {
643 dev_err(info->dev, "failed to allocate memory for extcon\n");
644 return -ENOMEM;
645 }
401
402 return 0;
403}
404
405static void rt8973a_muic_irq_work(struct work_struct *work)
406{
407 struct rt8973a_muic_info *info = container_of(work,
408 struct rt8973a_muic_info, irq_work);

--- 205 unchanged lines hidden (view full) ---

614 }
615
616 /* Allocate extcon device */
617 info->edev = devm_extcon_dev_allocate(info->dev, rt8973a_extcon_cable);
618 if (IS_ERR(info->edev)) {
619 dev_err(info->dev, "failed to allocate memory for extcon\n");
620 return -ENOMEM;
621 }
646 info->edev->name = np->name;
647
648 /* Register extcon device */
649 ret = devm_extcon_dev_register(info->dev, info->edev);
650 if (ret) {
651 dev_err(info->dev, "failed to register extcon device\n");
652 return ret;
653 }
654

--- 84 unchanged lines hidden ---
622
623 /* Register extcon device */
624 ret = devm_extcon_dev_register(info->dev, info->edev);
625 if (ret) {
626 dev_err(info->dev, "failed to register extcon device\n");
627 return ret;
628 }
629

--- 84 unchanged lines hidden ---