aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-07-28 02:11:14 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-07-28 02:11:14 -0400
commit16eb2bfc65ef86d3ac6420d50ddc2c48f0023cee (patch)
tree50f0163f007a90b0c8fcb2e5651cfbb5d6ed0596
parent7b9d1f0b7a18b86db0ac1de628fa91c0994fefbe (diff)
parentd3b503140e15d302bc55cf5a90226f0f85860bc2 (diff)
Merge tag 'extcon-next-for-3.17' of git://git.kernel.org/pub/scm/linux/kernel/git/chanwoo/extcon into char-misc-next
Chanwoo writes: Update extcon for v3.17 This patchset add new extcon provider driver and fix minor issue of extcon driver. Detailed description for patchset: 1. Add new Silicon-Mitus SM5502 MUIC (Micro-USB Interface Controller) device - extcon-sm5502 driver is capable of identifying the type of the external power source and attached accessory. And external power sources, such as Dedicated charger or a standard USB port, are able to charge the battery in the smart phone via the connector. 2. Fix minor issue of extcon driver - extcon-arizona driver - extcon-palmas driver - Remove unnecessary OOM messages for all extcon device drivers 3. Fix minor issue of extcon core - Re-order the sequence of extcon device driver in Kconfig/Makefile alphabitically - Set parent device of extcon device automatically using devm_extcon_dev_allocate() 4. Fix MAX77693 driver - This patchset has dependency on MFD/Regulator/Extcon. So, Lee Jones (MFD Maintainer) created Immutable branch between MFD and Extcon due for v3.17 merge-window and then I merged this patchset from MFD git repo[1] to Extcon git repo. [1] git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd (branch: ib-mfd-extcon-regulator)
-rw-r--r--Documentation/devicetree/bindings/extcon/extcon-sm5502.txt23
-rw-r--r--drivers/extcon/Kconfig38
-rw-r--r--drivers/extcon/Makefile7
-rw-r--r--drivers/extcon/extcon-adc-jack.c1
-rw-r--r--drivers/extcon/extcon-arizona.c74
-rw-r--r--drivers/extcon/extcon-class.c2
-rw-r--r--drivers/extcon/extcon-gpio.c1
-rw-r--r--drivers/extcon/extcon-max14577.c5
-rw-r--r--drivers/extcon/extcon-max77693.c41
-rw-r--r--drivers/extcon/extcon-max8997.c5
-rw-r--r--drivers/extcon/extcon-palmas.c3
-rw-r--r--drivers/extcon/extcon-sm5502.c724
-rw-r--r--drivers/mfd/Kconfig1
-rw-r--r--drivers/mfd/Makefile2
-rw-r--r--drivers/mfd/max77693-irq.c336
-rw-r--r--drivers/mfd/max77693.c210
-rw-r--r--drivers/regulator/max77693.c12
-rw-r--r--include/linux/extcon/sm5502.h287
-rw-r--r--include/linux/mfd/arizona/pdata.h3
-rw-r--r--include/linux/mfd/max77693-private.h54
20 files changed, 1335 insertions, 494 deletions
diff --git a/Documentation/devicetree/bindings/extcon/extcon-sm5502.txt b/Documentation/devicetree/bindings/extcon/extcon-sm5502.txt
new file mode 100644
index 000000000000..4ecda224955f
--- /dev/null
+++ b/Documentation/devicetree/bindings/extcon/extcon-sm5502.txt
@@ -0,0 +1,23 @@
1
2* SM5502 MUIC (Micro-USB Interface Controller) device
3
4The Silicon Mitus SM5502 is a MUIC (Micro-USB Interface Controller) device
5which can detect the state of external accessory when external accessory is
6attached or detached and button is pressed or released. It is interfaced to
7the host controller using an I2C interface.
8
9Required properties:
10- compatible: Should be "siliconmitus,sm5502-muic"
11- reg: Specifies the I2C slave address of the MUIC block. It should be 0x25
12- interrupt-parent: Specifies the phandle of the interrupt controller to which
13 the interrupts from sm5502 are delivered to.
14- interrupts: Interrupt specifiers for detection interrupt sources.
15
16Example:
17
18 sm5502@25 {
19 compatible = "siliconmitus,sm5502-muic";
20 interrupt-parent = <&gpx1>;
21 interrupts = <5 0>;
22 reg = <0x25>;
23 };
diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig
index aebde489c291..6f2f4727de2c 100644
--- a/drivers/extcon/Kconfig
+++ b/drivers/extcon/Kconfig
@@ -14,6 +14,20 @@ if EXTCON
14 14
15comment "Extcon Device Drivers" 15comment "Extcon Device Drivers"
16 16
17config EXTCON_ADC_JACK
18 tristate "ADC Jack extcon support"
19 depends on IIO
20 help
21 Say Y here to enable extcon device driver based on ADC values.
22
23config EXTCON_ARIZONA
24 tristate "Wolfson Arizona EXTCON support"
25 depends on MFD_ARIZONA && INPUT && SND_SOC
26 help
27 Say Y here to enable support for external accessory detection
28 with Wolfson Arizona devices. These are audio CODECs with
29 advanced audio accessory detection support.
30
17config EXTCON_GPIO 31config EXTCON_GPIO
18 tristate "GPIO extcon support" 32 tristate "GPIO extcon support"
19 depends on GPIOLIB 33 depends on GPIOLIB
@@ -21,12 +35,6 @@ config EXTCON_GPIO
21 Say Y here to enable GPIO based extcon support. Note that GPIO 35 Say Y here to enable GPIO based extcon support. Note that GPIO
22 extcon supports single state per extcon instance. 36 extcon supports single state per extcon instance.
23 37
24config EXTCON_ADC_JACK
25 tristate "ADC Jack extcon support"
26 depends on IIO
27 help
28 Say Y here to enable extcon device driver based on ADC values.
29
30config EXTCON_MAX14577 38config EXTCON_MAX14577
31 tristate "MAX14577/77836 EXTCON Support" 39 tristate "MAX14577/77836 EXTCON Support"
32 depends on MFD_MAX14577 40 depends on MFD_MAX14577
@@ -55,14 +63,6 @@ config EXTCON_MAX8997
55 Maxim MAX8997 PMIC. The MAX8997 MUIC is a USB port accessory 63 Maxim MAX8997 PMIC. The MAX8997 MUIC is a USB port accessory
56 detector and switch. 64 detector and switch.
57 65
58config EXTCON_ARIZONA
59 tristate "Wolfson Arizona EXTCON support"
60 depends on MFD_ARIZONA && INPUT && SND_SOC
61 help
62 Say Y here to enable support for external accessory detection
63 with Wolfson Arizona devices. These are audio CODECs with
64 advanced audio accessory detection support.
65
66config EXTCON_PALMAS 66config EXTCON_PALMAS
67 tristate "Palmas USB EXTCON support" 67 tristate "Palmas USB EXTCON support"
68 depends on MFD_PALMAS 68 depends on MFD_PALMAS
@@ -70,4 +70,14 @@ config EXTCON_PALMAS
70 Say Y here to enable support for USB peripheral and USB host 70 Say Y here to enable support for USB peripheral and USB host
71 detection by palmas usb. 71 detection by palmas usb.
72 72
73config EXTCON_SM5502
74 tristate "SM5502 EXTCON support"
75 select IRQ_DOMAIN
76 select REGMAP_I2C
77 select REGMAP_IRQ
78 help
79 If you say yes here you get support for the MUIC device of
80 Silicon Mitus SM5502. The SM5502 is a USB port accessory
81 detector and switch.
82
73endif # MULTISTATE_SWITCH 83endif # MULTISTATE_SWITCH
diff --git a/drivers/extcon/Makefile b/drivers/extcon/Makefile
index bf7861ec0906..b38546eb522a 100644
--- a/drivers/extcon/Makefile
+++ b/drivers/extcon/Makefile
@@ -1,12 +1,13 @@
1# 1
2# Makefile for external connector class (extcon) devices 2# Makefile for external connector class (extcon) devices
3# 3#
4 4
5obj-$(CONFIG_EXTCON) += extcon-class.o 5obj-$(CONFIG_EXTCON) += extcon-class.o
6obj-$(CONFIG_EXTCON_GPIO) += extcon-gpio.o
7obj-$(CONFIG_EXTCON_ADC_JACK) += extcon-adc-jack.o 6obj-$(CONFIG_EXTCON_ADC_JACK) += extcon-adc-jack.o
7obj-$(CONFIG_EXTCON_ARIZONA) += extcon-arizona.o
8obj-$(CONFIG_EXTCON_GPIO) += extcon-gpio.o
8obj-$(CONFIG_EXTCON_MAX14577) += extcon-max14577.o 9obj-$(CONFIG_EXTCON_MAX14577) += extcon-max14577.o
9obj-$(CONFIG_EXTCON_MAX77693) += extcon-max77693.o 10obj-$(CONFIG_EXTCON_MAX77693) += extcon-max77693.o
10obj-$(CONFIG_EXTCON_MAX8997) += extcon-max8997.o 11obj-$(CONFIG_EXTCON_MAX8997) += extcon-max8997.o
11obj-$(CONFIG_EXTCON_ARIZONA) += extcon-arizona.o
12obj-$(CONFIG_EXTCON_PALMAS) += extcon-palmas.o 12obj-$(CONFIG_EXTCON_PALMAS) += extcon-palmas.o
13obj-$(CONFIG_EXTCON_SM5502) += extcon-sm5502.o
diff --git a/drivers/extcon/extcon-adc-jack.c b/drivers/extcon/extcon-adc-jack.c
index e18f95be3733..d860229e4de1 100644
--- a/drivers/extcon/extcon-adc-jack.c
+++ b/drivers/extcon/extcon-adc-jack.c
@@ -112,7 +112,6 @@ static int adc_jack_probe(struct platform_device *pdev)
112 dev_err(&pdev->dev, "failed to allocate extcon device\n"); 112 dev_err(&pdev->dev, "failed to allocate extcon device\n");
113 return -ENOMEM; 113 return -ENOMEM;
114 } 114 }
115 data->edev->dev.parent = &pdev->dev;
116 data->edev->name = pdata->name; 115 data->edev->name = pdata->name;
117 116
118 /* Check the length of array and set num_cables */ 117 /* Check the length of array and set num_cables */
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c
index 6c84e3d12043..ba51588cc000 100644
--- a/drivers/extcon/extcon-arizona.c
+++ b/drivers/extcon/extcon-arizona.c
@@ -39,6 +39,11 @@
39#define ARIZONA_ACCDET_MODE_HPL 1 39#define ARIZONA_ACCDET_MODE_HPL 1
40#define ARIZONA_ACCDET_MODE_HPR 2 40#define ARIZONA_ACCDET_MODE_HPR 2
41 41
42#define ARIZONA_MICD_CLAMP_MODE_JDL 0x4
43#define ARIZONA_MICD_CLAMP_MODE_JDH 0x5
44#define ARIZONA_MICD_CLAMP_MODE_JDL_GP5H 0x9
45#define ARIZONA_MICD_CLAMP_MODE_JDH_GP5H 0xb
46
42#define ARIZONA_HPDET_MAX 10000 47#define ARIZONA_HPDET_MAX 10000
43 48
44#define HPDET_DEBOUNCE 500 49#define HPDET_DEBOUNCE 500
@@ -324,14 +329,17 @@ static void arizona_stop_mic(struct arizona_extcon_info *info)
324} 329}
325 330
326static struct { 331static struct {
332 unsigned int threshold;
327 unsigned int factor_a; 333 unsigned int factor_a;
328 unsigned int factor_b; 334 unsigned int factor_b;
329} arizona_hpdet_b_ranges[] = { 335} arizona_hpdet_b_ranges[] = {
330 { 5528, 362464 }, 336 { 100, 5528, 362464 },
331 { 11084, 6186851 }, 337 { 169, 11084, 6186851 },
332 { 11065, 65460395 }, 338 { 169, 11065, 65460395 },
333}; 339};
334 340
341#define ARIZONA_HPDET_B_RANGE_MAX 0x3fb
342
335static struct { 343static struct {
336 int min; 344 int min;
337 int max; 345 int max;
@@ -386,7 +394,8 @@ static int arizona_hpdet_read(struct arizona_extcon_info *info)
386 >> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT; 394 >> ARIZONA_HP_IMPEDANCE_RANGE_SHIFT;
387 395
388 if (range < ARRAY_SIZE(arizona_hpdet_b_ranges) - 1 && 396 if (range < ARRAY_SIZE(arizona_hpdet_b_ranges) - 1 &&
389 (val < 100 || val >= 0x3fb)) { 397 (val < arizona_hpdet_b_ranges[range].threshold ||
398 val >= ARIZONA_HPDET_B_RANGE_MAX)) {
390 range++; 399 range++;
391 dev_dbg(arizona->dev, "Moving to HPDET range %d\n", 400 dev_dbg(arizona->dev, "Moving to HPDET range %d\n",
392 range); 401 range);
@@ -399,7 +408,8 @@ static int arizona_hpdet_read(struct arizona_extcon_info *info)
399 } 408 }
400 409
401 /* If we go out of range report top of range */ 410 /* If we go out of range report top of range */
402 if (val < 100 || val >= 0x3fb) { 411 if (val < arizona_hpdet_b_ranges[range].threshold ||
412 val >= ARIZONA_HPDET_B_RANGE_MAX) {
403 dev_dbg(arizona->dev, "Measurement out of range\n"); 413 dev_dbg(arizona->dev, "Measurement out of range\n");
404 return ARIZONA_HPDET_MAX; 414 return ARIZONA_HPDET_MAX;
405 } 415 }
@@ -664,9 +674,8 @@ err:
664 ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC); 674 ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
665 675
666 /* Just report headphone */ 676 /* Just report headphone */
667 ret = extcon_update_state(info->edev, 677 ret = extcon_set_cable_state_(info->edev,
668 1 << ARIZONA_CABLE_HEADPHONE, 678 ARIZONA_CABLE_HEADPHONE, true);
669 1 << ARIZONA_CABLE_HEADPHONE);
670 if (ret != 0) 679 if (ret != 0)
671 dev_err(arizona->dev, "Failed to report headphone: %d\n", ret); 680 dev_err(arizona->dev, "Failed to report headphone: %d\n", ret);
672 681
@@ -723,9 +732,8 @@ err:
723 ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC); 732 ARIZONA_ACCDET_MODE_MASK, ARIZONA_ACCDET_MODE_MIC);
724 733
725 /* Just report headphone */ 734 /* Just report headphone */
726 ret = extcon_update_state(info->edev, 735 ret = extcon_set_cable_state_(info->edev,
727 1 << ARIZONA_CABLE_HEADPHONE, 736 ARIZONA_CABLE_HEADPHONE, true);
728 1 << ARIZONA_CABLE_HEADPHONE);
729 if (ret != 0) 737 if (ret != 0)
730 dev_err(arizona->dev, "Failed to report headphone: %d\n", ret); 738 dev_err(arizona->dev, "Failed to report headphone: %d\n", ret);
731 739
@@ -812,16 +820,15 @@ static void arizona_micd_detect(struct work_struct *work)
812 if (info->detecting && (val & ARIZONA_MICD_LVL_8)) { 820 if (info->detecting && (val & ARIZONA_MICD_LVL_8)) {
813 arizona_identify_headphone(info); 821 arizona_identify_headphone(info);
814 822
815 ret = extcon_update_state(info->edev, 823 ret = extcon_set_cable_state_(info->edev,
816 1 << ARIZONA_CABLE_MICROPHONE, 824 ARIZONA_CABLE_MICROPHONE, true);
817 1 << ARIZONA_CABLE_MICROPHONE);
818 825
819 if (ret != 0) 826 if (ret != 0)
820 dev_err(arizona->dev, "Headset report failed: %d\n", 827 dev_err(arizona->dev, "Headset report failed: %d\n",
821 ret); 828 ret);
822 829
823 /* Don't need to regulate for button detection */ 830 /* Don't need to regulate for button detection */
824 ret = regulator_allow_bypass(info->micvdd, false); 831 ret = regulator_allow_bypass(info->micvdd, true);
825 if (ret != 0) { 832 if (ret != 0) {
826 dev_err(arizona->dev, "Failed to bypass MICVDD: %d\n", 833 dev_err(arizona->dev, "Failed to bypass MICVDD: %d\n",
827 ret); 834 ret);
@@ -962,10 +969,16 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
962 969
963 if (arizona->pdata.jd_gpio5) { 970 if (arizona->pdata.jd_gpio5) {
964 mask = ARIZONA_MICD_CLAMP_STS; 971 mask = ARIZONA_MICD_CLAMP_STS;
965 present = 0; 972 if (arizona->pdata.jd_invert)
973 present = ARIZONA_MICD_CLAMP_STS;
974 else
975 present = 0;
966 } else { 976 } else {
967 mask = ARIZONA_JD1_STS; 977 mask = ARIZONA_JD1_STS;
968 present = ARIZONA_JD1_STS; 978 if (arizona->pdata.jd_invert)
979 present = 0;
980 else
981 present = ARIZONA_JD1_STS;
969 } 982 }
970 983
971 ret = regmap_read(arizona->regmap, ARIZONA_AOD_IRQ_RAW_STATUS, &val); 984 ret = regmap_read(arizona->regmap, ARIZONA_AOD_IRQ_RAW_STATUS, &val);
@@ -1096,6 +1109,7 @@ static int arizona_extcon_probe(struct platform_device *pdev)
1096 struct arizona_pdata *pdata = &arizona->pdata; 1109 struct arizona_pdata *pdata = &arizona->pdata;
1097 struct arizona_extcon_info *info; 1110 struct arizona_extcon_info *info;
1098 unsigned int val; 1111 unsigned int val;
1112 unsigned int clamp_mode;
1099 int jack_irq_fall, jack_irq_rise; 1113 int jack_irq_fall, jack_irq_rise;
1100 int ret, mode, i, j; 1114 int ret, mode, i, j;
1101 1115
@@ -1103,12 +1117,10 @@ static int arizona_extcon_probe(struct platform_device *pdev)
1103 return -EPROBE_DEFER; 1117 return -EPROBE_DEFER;
1104 1118
1105 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); 1119 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
1106 if (!info) { 1120 if (!info)
1107 dev_err(&pdev->dev, "Failed to allocate memory\n");
1108 return -ENOMEM; 1121 return -ENOMEM;
1109 }
1110 1122
1111 info->micvdd = devm_regulator_get(arizona->dev, "MICVDD"); 1123 info->micvdd = devm_regulator_get(&pdev->dev, "MICVDD");
1112 if (IS_ERR(info->micvdd)) { 1124 if (IS_ERR(info->micvdd)) {
1113 ret = PTR_ERR(info->micvdd); 1125 ret = PTR_ERR(info->micvdd);
1114 dev_err(arizona->dev, "Failed to get MICVDD: %d\n", ret); 1126 dev_err(arizona->dev, "Failed to get MICVDD: %d\n", ret);
@@ -1156,7 +1168,6 @@ static int arizona_extcon_probe(struct platform_device *pdev)
1156 return -ENOMEM; 1168 return -ENOMEM;
1157 } 1169 }
1158 info->edev->name = "Headset Jack"; 1170 info->edev->name = "Headset Jack";
1159 info->edev->dev.parent = arizona->dev;
1160 1171
1161 ret = devm_extcon_dev_register(&pdev->dev, info->edev); 1172 ret = devm_extcon_dev_register(&pdev->dev, info->edev);
1162 if (ret < 0) { 1173 if (ret < 0) {
@@ -1174,7 +1185,6 @@ static int arizona_extcon_probe(struct platform_device *pdev)
1174 1185
1175 info->input->name = "Headset"; 1186 info->input->name = "Headset";
1176 info->input->phys = "arizona/extcon"; 1187 info->input->phys = "arizona/extcon";
1177 info->input->dev.parent = &pdev->dev;
1178 1188
1179 if (pdata->num_micd_configs) { 1189 if (pdata->num_micd_configs) {
1180 info->micd_modes = pdata->micd_configs; 1190 info->micd_modes = pdata->micd_configs;
@@ -1305,16 +1315,22 @@ static int arizona_extcon_probe(struct platform_device *pdev)
1305 regmap_write(arizona->regmap, ARIZONA_GPIO5_CTRL, 1315 regmap_write(arizona->regmap, ARIZONA_GPIO5_CTRL,
1306 val); 1316 val);
1307 1317
1308 regmap_update_bits(arizona->regmap, 1318 if (arizona->pdata.jd_invert)
1309 ARIZONA_MICD_CLAMP_CONTROL, 1319 clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDH_GP5H;
1310 ARIZONA_MICD_CLAMP_MODE_MASK, 0x9); 1320 else
1321 clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDL_GP5H;
1311 } else { 1322 } else {
1312 regmap_update_bits(arizona->regmap, 1323 if (arizona->pdata.jd_invert)
1313 ARIZONA_MICD_CLAMP_CONTROL, 1324 clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDH;
1314 ARIZONA_MICD_CLAMP_MODE_MASK, 0x4); 1325 else
1326 clamp_mode = ARIZONA_MICD_CLAMP_MODE_JDL;
1315 } 1327 }
1316 1328
1317 regmap_update_bits(arizona->regmap, 1329 regmap_update_bits(arizona->regmap,
1330 ARIZONA_MICD_CLAMP_CONTROL,
1331 ARIZONA_MICD_CLAMP_MODE_MASK, clamp_mode);
1332
1333 regmap_update_bits(arizona->regmap,
1318 ARIZONA_JACK_DETECT_DEBOUNCE, 1334 ARIZONA_JACK_DETECT_DEBOUNCE,
1319 ARIZONA_MICD_CLAMP_DB, 1335 ARIZONA_MICD_CLAMP_DB,
1320 ARIZONA_MICD_CLAMP_DB); 1336 ARIZONA_MICD_CLAMP_DB);
diff --git a/drivers/extcon/extcon-class.c b/drivers/extcon/extcon-class.c
index 18d42c0e4581..4c2f2c543bb7 100644
--- a/drivers/extcon/extcon-class.c
+++ b/drivers/extcon/extcon-class.c
@@ -645,6 +645,8 @@ struct extcon_dev *devm_extcon_dev_allocate(struct device *dev,
645 return edev; 645 return edev;
646 } 646 }
647 647
648 edev->dev.parent = dev;
649
648 *ptr = edev; 650 *ptr = edev;
649 devres_add(dev, ptr); 651 devres_add(dev, ptr);
650 652
diff --git a/drivers/extcon/extcon-gpio.c b/drivers/extcon/extcon-gpio.c
index 645b28356819..5b7ec274cb63 100644
--- a/drivers/extcon/extcon-gpio.c
+++ b/drivers/extcon/extcon-gpio.c
@@ -105,7 +105,6 @@ static int gpio_extcon_probe(struct platform_device *pdev)
105 return -ENOMEM; 105 return -ENOMEM;
106 } 106 }
107 extcon_data->edev->name = pdata->name; 107 extcon_data->edev->name = pdata->name;
108 extcon_data->edev->dev.parent = &pdev->dev;
109 108
110 extcon_data->gpio = pdata->gpio; 109 extcon_data->gpio = pdata->gpio;
111 extcon_data->gpio_active_low = pdata->gpio_active_low; 110 extcon_data->gpio_active_low = pdata->gpio_active_low;
diff --git a/drivers/extcon/extcon-max14577.c b/drivers/extcon/extcon-max14577.c
index d49e891b5675..7309743d0da1 100644
--- a/drivers/extcon/extcon-max14577.c
+++ b/drivers/extcon/extcon-max14577.c
@@ -692,10 +692,9 @@ static int max14577_muic_probe(struct platform_device *pdev)
692 u8 id; 692 u8 id;
693 693
694 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); 694 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
695 if (!info) { 695 if (!info)
696 dev_err(&pdev->dev, "failed to allocate memory\n");
697 return -ENOMEM; 696 return -ENOMEM;
698 } 697
699 info->dev = &pdev->dev; 698 info->dev = &pdev->dev;
700 info->max14577 = max14577; 699 info->max14577 = max14577;
701 700
diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c
index 2c7c3e191591..77460f2c1ca1 100644
--- a/drivers/extcon/extcon-max77693.c
+++ b/drivers/extcon/extcon-max77693.c
@@ -255,10 +255,10 @@ static int max77693_muic_set_debounce_time(struct max77693_muic_info *info,
255 case ADC_DEBOUNCE_TIME_10MS: 255 case ADC_DEBOUNCE_TIME_10MS:
256 case ADC_DEBOUNCE_TIME_25MS: 256 case ADC_DEBOUNCE_TIME_25MS:
257 case ADC_DEBOUNCE_TIME_38_62MS: 257 case ADC_DEBOUNCE_TIME_38_62MS:
258 ret = max77693_update_reg(info->max77693->regmap_muic, 258 ret = regmap_update_bits(info->max77693->regmap_muic,
259 MAX77693_MUIC_REG_CTRL3, 259 MAX77693_MUIC_REG_CTRL3,
260 time << CONTROL3_ADCDBSET_SHIFT, 260 CONTROL3_ADCDBSET_MASK,
261 CONTROL3_ADCDBSET_MASK); 261 time << CONTROL3_ADCDBSET_SHIFT);
262 if (ret) { 262 if (ret) {
263 dev_err(info->dev, "failed to set ADC debounce time\n"); 263 dev_err(info->dev, "failed to set ADC debounce time\n");
264 return ret; 264 return ret;
@@ -286,15 +286,15 @@ static int max77693_muic_set_path(struct max77693_muic_info *info,
286 u8 val, bool attached) 286 u8 val, bool attached)
287{ 287{
288 int ret = 0; 288 int ret = 0;
289 u8 ctrl1, ctrl2 = 0; 289 unsigned int ctrl1, ctrl2 = 0;
290 290
291 if (attached) 291 if (attached)
292 ctrl1 = val; 292 ctrl1 = val;
293 else 293 else
294 ctrl1 = CONTROL1_SW_OPEN; 294 ctrl1 = CONTROL1_SW_OPEN;
295 295
296 ret = max77693_update_reg(info->max77693->regmap_muic, 296 ret = regmap_update_bits(info->max77693->regmap_muic,
297 MAX77693_MUIC_REG_CTRL1, ctrl1, COMP_SW_MASK); 297 MAX77693_MUIC_REG_CTRL1, COMP_SW_MASK, ctrl1);
298 if (ret < 0) { 298 if (ret < 0) {
299 dev_err(info->dev, "failed to update MUIC register\n"); 299 dev_err(info->dev, "failed to update MUIC register\n");
300 return ret; 300 return ret;
@@ -305,9 +305,9 @@ static int max77693_muic_set_path(struct max77693_muic_info *info,
305 else 305 else
306 ctrl2 |= CONTROL2_LOWPWR_MASK; /* LowPwr=1, CPEn=0 */ 306 ctrl2 |= CONTROL2_LOWPWR_MASK; /* LowPwr=1, CPEn=0 */
307 307
308 ret = max77693_update_reg(info->max77693->regmap_muic, 308 ret = regmap_update_bits(info->max77693->regmap_muic,
309 MAX77693_MUIC_REG_CTRL2, ctrl2, 309 MAX77693_MUIC_REG_CTRL2,
310 CONTROL2_LOWPWR_MASK | CONTROL2_CPEN_MASK); 310 CONTROL2_LOWPWR_MASK | CONTROL2_CPEN_MASK, ctrl2);
311 if (ret < 0) { 311 if (ret < 0) {
312 dev_err(info->dev, "failed to update MUIC register\n"); 312 dev_err(info->dev, "failed to update MUIC register\n");
313 return ret; 313 return ret;
@@ -969,8 +969,8 @@ static void max77693_muic_irq_work(struct work_struct *work)
969 if (info->irq == muic_irqs[i].virq) 969 if (info->irq == muic_irqs[i].virq)
970 irq_type = muic_irqs[i].irq; 970 irq_type = muic_irqs[i].irq;
971 971
972 ret = max77693_bulk_read(info->max77693->regmap_muic, 972 ret = regmap_bulk_read(info->max77693->regmap_muic,
973 MAX77693_MUIC_REG_STATUS1, 2, info->status); 973 MAX77693_MUIC_REG_STATUS1, info->status, 2);
974 if (ret) { 974 if (ret) {
975 dev_err(info->dev, "failed to read MUIC register\n"); 975 dev_err(info->dev, "failed to read MUIC register\n");
976 mutex_unlock(&info->mutex); 976 mutex_unlock(&info->mutex);
@@ -1042,8 +1042,8 @@ static int max77693_muic_detect_accessory(struct max77693_muic_info *info)
1042 mutex_lock(&info->mutex); 1042 mutex_lock(&info->mutex);
1043 1043
1044 /* Read STATUSx register to detect accessory */ 1044 /* Read STATUSx register to detect accessory */
1045 ret = max77693_bulk_read(info->max77693->regmap_muic, 1045 ret = regmap_bulk_read(info->max77693->regmap_muic,
1046 MAX77693_MUIC_REG_STATUS1, 2, info->status); 1046 MAX77693_MUIC_REG_STATUS1, info->status, 2);
1047 if (ret) { 1047 if (ret) {
1048 dev_err(info->dev, "failed to read MUIC register\n"); 1048 dev_err(info->dev, "failed to read MUIC register\n");
1049 mutex_unlock(&info->mutex); 1049 mutex_unlock(&info->mutex);
@@ -1095,14 +1095,13 @@ static int max77693_muic_probe(struct platform_device *pdev)
1095 int delay_jiffies; 1095 int delay_jiffies;
1096 int ret; 1096 int ret;
1097 int i; 1097 int i;
1098 u8 id; 1098 unsigned int id;
1099 1099
1100 info = devm_kzalloc(&pdev->dev, sizeof(struct max77693_muic_info), 1100 info = devm_kzalloc(&pdev->dev, sizeof(struct max77693_muic_info),
1101 GFP_KERNEL); 1101 GFP_KERNEL);
1102 if (!info) { 1102 if (!info)
1103 dev_err(&pdev->dev, "failed to allocate memory\n");
1104 return -ENOMEM; 1103 return -ENOMEM;
1105 } 1104
1106 info->dev = &pdev->dev; 1105 info->dev = &pdev->dev;
1107 info->max77693 = max77693; 1106 info->max77693 = max77693;
1108 if (info->max77693->regmap_muic) { 1107 if (info->max77693->regmap_muic) {
@@ -1154,7 +1153,8 @@ static int max77693_muic_probe(struct platform_device *pdev)
1154 struct max77693_muic_irq *muic_irq = &muic_irqs[i]; 1153 struct max77693_muic_irq *muic_irq = &muic_irqs[i];
1155 unsigned int virq = 0; 1154 unsigned int virq = 0;
1156 1155
1157 virq = irq_create_mapping(max77693->irq_domain, muic_irq->irq); 1156 virq = regmap_irq_get_virq(max77693->irq_data_muic,
1157 muic_irq->irq);
1158 if (!virq) { 1158 if (!virq) {
1159 ret = -EINVAL; 1159 ret = -EINVAL;
1160 goto err_irq; 1160 goto err_irq;
@@ -1183,7 +1183,6 @@ static int max77693_muic_probe(struct platform_device *pdev)
1183 goto err_irq; 1183 goto err_irq;
1184 } 1184 }
1185 info->edev->name = DEV_NAME; 1185 info->edev->name = DEV_NAME;
1186 info->edev->dev.parent = &pdev->dev;
1187 1186
1188 ret = devm_extcon_dev_register(&pdev->dev, info->edev); 1187 ret = devm_extcon_dev_register(&pdev->dev, info->edev);
1189 if (ret) { 1188 if (ret) {
@@ -1204,7 +1203,7 @@ static int max77693_muic_probe(struct platform_device *pdev)
1204 enum max77693_irq_source irq_src 1203 enum max77693_irq_source irq_src
1205 = MAX77693_IRQ_GROUP_NR; 1204 = MAX77693_IRQ_GROUP_NR;
1206 1205
1207 max77693_write_reg(info->max77693->regmap_muic, 1206 regmap_write(info->max77693->regmap_muic,
1208 init_data[i].addr, 1207 init_data[i].addr,
1209 init_data[i].data); 1208 init_data[i].data);
1210 1209
@@ -1262,7 +1261,7 @@ static int max77693_muic_probe(struct platform_device *pdev)
1262 max77693_muic_set_path(info, info->path_uart, true); 1261 max77693_muic_set_path(info, info->path_uart, true);
1263 1262
1264 /* Check revision number of MUIC device*/ 1263 /* Check revision number of MUIC device*/
1265 ret = max77693_read_reg(info->max77693->regmap_muic, 1264 ret = regmap_read(info->max77693->regmap_muic,
1266 MAX77693_MUIC_REG_ID, &id); 1265 MAX77693_MUIC_REG_ID, &id);
1267 if (ret < 0) { 1266 if (ret < 0) {
1268 dev_err(&pdev->dev, "failed to read revision number\n"); 1267 dev_err(&pdev->dev, "failed to read revision number\n");
diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c
index d9f7f1baaa03..75e501c98005 100644
--- a/drivers/extcon/extcon-max8997.c
+++ b/drivers/extcon/extcon-max8997.c
@@ -661,10 +661,8 @@ static int max8997_muic_probe(struct platform_device *pdev)
661 661
662 info = devm_kzalloc(&pdev->dev, sizeof(struct max8997_muic_info), 662 info = devm_kzalloc(&pdev->dev, sizeof(struct max8997_muic_info),
663 GFP_KERNEL); 663 GFP_KERNEL);
664 if (!info) { 664 if (!info)
665 dev_err(&pdev->dev, "failed to allocate memory\n");
666 return -ENOMEM; 665 return -ENOMEM;
667 }
668 666
669 info->dev = &pdev->dev; 667 info->dev = &pdev->dev;
670 info->muic = max8997->muic; 668 info->muic = max8997->muic;
@@ -706,7 +704,6 @@ static int max8997_muic_probe(struct platform_device *pdev)
706 goto err_irq; 704 goto err_irq;
707 } 705 }
708 info->edev->name = DEV_NAME; 706 info->edev->name = DEV_NAME;
709 info->edev->dev.parent = &pdev->dev;
710 707
711 ret = devm_extcon_dev_register(&pdev->dev, info->edev); 708 ret = devm_extcon_dev_register(&pdev->dev, info->edev);
712 if (ret) { 709 if (ret) {
diff --git a/drivers/extcon/extcon-palmas.c b/drivers/extcon/extcon-palmas.c
index 7417ce84eb2d..230e1220ce48 100644
--- a/drivers/extcon/extcon-palmas.c
+++ b/drivers/extcon/extcon-palmas.c
@@ -194,7 +194,6 @@ static int palmas_usb_probe(struct platform_device *pdev)
194 return -ENOMEM; 194 return -ENOMEM;
195 } 195 }
196 palmas_usb->edev->name = kstrdup(node->name, GFP_KERNEL); 196 palmas_usb->edev->name = kstrdup(node->name, GFP_KERNEL);
197 palmas_usb->edev->dev.parent = palmas_usb->dev;
198 palmas_usb->edev->mutually_exclusive = mutually_exclusive; 197 palmas_usb->edev->mutually_exclusive = mutually_exclusive;
199 198
200 status = devm_extcon_dev_register(&pdev->dev, palmas_usb->edev); 199 status = devm_extcon_dev_register(&pdev->dev, palmas_usb->edev);
@@ -278,7 +277,7 @@ static int palmas_usb_resume(struct device *dev)
278 277
279static SIMPLE_DEV_PM_OPS(palmas_pm_ops, palmas_usb_suspend, palmas_usb_resume); 278static SIMPLE_DEV_PM_OPS(palmas_pm_ops, palmas_usb_suspend, palmas_usb_resume);
280 279
281static struct of_device_id of_palmas_match_tbl[] = { 280static const struct of_device_id of_palmas_match_tbl[] = {
282 { .compatible = "ti,palmas-usb", }, 281 { .compatible = "ti,palmas-usb", },
283 { .compatible = "ti,palmas-usb-vid", }, 282 { .compatible = "ti,palmas-usb-vid", },
284 { .compatible = "ti,twl6035-usb", }, 283 { .compatible = "ti,twl6035-usb", },
diff --git a/drivers/extcon/extcon-sm5502.c b/drivers/extcon/extcon-sm5502.c
new file mode 100644
index 000000000000..560d7dccec7b
--- /dev/null
+++ b/drivers/extcon/extcon-sm5502.c
@@ -0,0 +1,724 @@
1/*
2 * extcon-sm5502.c - Silicon Mitus SM5502 extcon drvier 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
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * 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/err.h>
19#include <linux/i2c.h>
20#include <linux/input.h>
21#include <linux/interrupt.h>
22#include <linux/irqdomain.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/platform_device.h>
26#include <linux/regmap.h>
27#include <linux/slab.h>
28#include <linux/extcon.h>
29#include <linux/extcon/sm5502.h>
30
31#define DELAY_MS_DEFAULT 17000 /* unit: millisecond */
32
33struct muic_irq {
34 unsigned int irq;
35 const char *name;
36 unsigned int virq;
37};
38
39struct reg_data {
40 u8 reg;
41 unsigned int val;
42 bool invert;
43};
44
45struct sm5502_muic_info {
46 struct device *dev;
47 struct extcon_dev *edev;
48
49 struct i2c_client *i2c;
50 struct regmap *regmap;
51
52 struct regmap_irq_chip_data *irq_data;
53 struct muic_irq *muic_irqs;
54 unsigned int num_muic_irqs;
55 int irq;
56 bool irq_attach;
57 bool irq_detach;
58 struct work_struct irq_work;
59
60 struct reg_data *reg_data;
61 unsigned int num_reg_data;
62
63 struct mutex mutex;
64
65 /*
66 * Use delayed workqueue to detect cable state and then
67 * notify cable state to notifiee/platform through uevent.
68 * After completing the booting of platform, the extcon provider
69 * driver should notify cable state to upper layer.
70 */
71 struct delayed_work wq_detcable;
72};
73
74/* Default value of SM5502 register to bring up MUIC device. */
75static struct reg_data sm5502_reg_data[] = {
76 {
77 .reg = SM5502_REG_CONTROL,
78 .val = SM5502_REG_CONTROL_MASK_INT_MASK,
79 .invert = false,
80 }, {
81 .reg = SM5502_REG_INTMASK1,
82 .val = SM5502_REG_INTM1_KP_MASK
83 | SM5502_REG_INTM1_LKP_MASK
84 | SM5502_REG_INTM1_LKR_MASK,
85 .invert = true,
86 }, {
87 .reg = SM5502_REG_INTMASK2,
88 .val = SM5502_REG_INTM2_VBUS_DET_MASK
89 | SM5502_REG_INTM2_REV_ACCE_MASK
90 | SM5502_REG_INTM2_ADC_CHG_MASK
91 | SM5502_REG_INTM2_STUCK_KEY_MASK
92 | SM5502_REG_INTM2_STUCK_KEY_RCV_MASK
93 | SM5502_REG_INTM2_MHL_MASK,
94 .invert = true,
95 },
96 { }
97};
98
99/* List of detectable cables */
100enum {
101 EXTCON_CABLE_USB = 0,
102 EXTCON_CABLE_USB_HOST,
103 EXTCON_CABLE_TA,
104
105 EXTCON_CABLE_END,
106};
107
108static const char *sm5502_extcon_cable[] = {
109 [EXTCON_CABLE_USB] = "USB",
110 [EXTCON_CABLE_USB_HOST] = "USB-Host",
111 [EXTCON_CABLE_TA] = "TA",
112 NULL,
113};
114
115/* Define supported accessory type */
116enum sm5502_muic_acc_type {
117 SM5502_MUIC_ADC_GROUND = 0x0,
118 SM5502_MUIC_ADC_SEND_END_BUTTON,
119 SM5502_MUIC_ADC_REMOTE_S1_BUTTON,
120 SM5502_MUIC_ADC_REMOTE_S2_BUTTON,
121 SM5502_MUIC_ADC_REMOTE_S3_BUTTON,
122 SM5502_MUIC_ADC_REMOTE_S4_BUTTON,
123 SM5502_MUIC_ADC_REMOTE_S5_BUTTON,
124 SM5502_MUIC_ADC_REMOTE_S6_BUTTON,
125 SM5502_MUIC_ADC_REMOTE_S7_BUTTON,
126 SM5502_MUIC_ADC_REMOTE_S8_BUTTON,
127 SM5502_MUIC_ADC_REMOTE_S9_BUTTON,
128 SM5502_MUIC_ADC_REMOTE_S10_BUTTON,
129 SM5502_MUIC_ADC_REMOTE_S11_BUTTON,
130 SM5502_MUIC_ADC_REMOTE_S12_BUTTON,
131 SM5502_MUIC_ADC_RESERVED_ACC_1,
132 SM5502_MUIC_ADC_RESERVED_ACC_2,
133 SM5502_MUIC_ADC_RESERVED_ACC_3,
134 SM5502_MUIC_ADC_RESERVED_ACC_4,
135 SM5502_MUIC_ADC_RESERVED_ACC_5,
136 SM5502_MUIC_ADC_AUDIO_TYPE2,
137 SM5502_MUIC_ADC_PHONE_POWERED_DEV,
138 SM5502_MUIC_ADC_TTY_CONVERTER,
139 SM5502_MUIC_ADC_UART_CABLE,
140 SM5502_MUIC_ADC_TYPE1_CHARGER,
141 SM5502_MUIC_ADC_FACTORY_MODE_BOOT_OFF_USB,
142 SM5502_MUIC_ADC_FACTORY_MODE_BOOT_ON_USB,
143 SM5502_MUIC_ADC_AUDIO_VIDEO_CABLE,
144 SM5502_MUIC_ADC_TYPE2_CHARGER,
145 SM5502_MUIC_ADC_FACTORY_MODE_BOOT_OFF_UART,
146 SM5502_MUIC_ADC_FACTORY_MODE_BOOT_ON_UART,
147 SM5502_MUIC_ADC_AUDIO_TYPE1,
148 SM5502_MUIC_ADC_OPEN = 0x1f,
149
150 /* The below accessories have same ADC value (0x1f or 0x1e).
151 So, Device type1 is used to separate specific accessory. */
152 /* |---------|--ADC| */
153 /* | [7:5]|[4:0]| */
154 SM5502_MUIC_ADC_AUDIO_TYPE1_FULL_REMOTE = 0x3e, /* | 001|11110| */
155 SM5502_MUIC_ADC_AUDIO_TYPE1_SEND_END = 0x5e, /* | 010|11110| */
156 /* |Dev Type1|--ADC| */
157 SM5502_MUIC_ADC_OPEN_USB = 0x5f, /* | 010|11111| */
158 SM5502_MUIC_ADC_OPEN_TA = 0xdf, /* | 110|11111| */
159 SM5502_MUIC_ADC_OPEN_USB_OTG = 0xff, /* | 111|11111| */
160};
161
162/* List of supported interrupt for SM5502 */
163static struct muic_irq sm5502_muic_irqs[] = {
164 { SM5502_IRQ_INT1_ATTACH, "muic-attach" },
165 { SM5502_IRQ_INT1_DETACH, "muic-detach" },
166 { SM5502_IRQ_INT1_KP, "muic-kp" },
167 { SM5502_IRQ_INT1_LKP, "muic-lkp" },
168 { SM5502_IRQ_INT1_LKR, "muic-lkr" },
169 { SM5502_IRQ_INT1_OVP_EVENT, "muic-ovp-event" },
170 { SM5502_IRQ_INT1_OCP_EVENT, "muic-ocp-event" },
171 { SM5502_IRQ_INT1_OVP_OCP_DIS, "muic-ovp-ocp-dis" },
172 { SM5502_IRQ_INT2_VBUS_DET, "muic-vbus-det" },
173 { SM5502_IRQ_INT2_REV_ACCE, "muic-rev-acce" },
174 { SM5502_IRQ_INT2_ADC_CHG, "muic-adc-chg" },
175 { SM5502_IRQ_INT2_STUCK_KEY, "muic-stuck-key" },
176 { SM5502_IRQ_INT2_STUCK_KEY_RCV, "muic-stuck-key-rcv" },
177 { SM5502_IRQ_INT2_MHL, "muic-mhl" },
178};
179
180/* Define interrupt list of SM5502 to register regmap_irq */
181static const struct regmap_irq sm5502_irqs[] = {
182 /* INT1 interrupts */
183 { .reg_offset = 0, .mask = SM5502_IRQ_INT1_ATTACH_MASK, },
184 { .reg_offset = 0, .mask = SM5502_IRQ_INT1_DETACH_MASK, },
185 { .reg_offset = 0, .mask = SM5502_IRQ_INT1_KP_MASK, },
186 { .reg_offset = 0, .mask = SM5502_IRQ_INT1_LKP_MASK, },
187 { .reg_offset = 0, .mask = SM5502_IRQ_INT1_LKR_MASK, },
188 { .reg_offset = 0, .mask = SM5502_IRQ_INT1_OVP_EVENT_MASK, },
189 { .reg_offset = 0, .mask = SM5502_IRQ_INT1_OCP_EVENT_MASK, },
190 { .reg_offset = 0, .mask = SM5502_IRQ_INT1_OVP_OCP_DIS_MASK, },
191
192 /* INT2 interrupts */
193 { .reg_offset = 1, .mask = SM5502_IRQ_INT2_VBUS_DET_MASK,},
194 { .reg_offset = 1, .mask = SM5502_IRQ_INT2_REV_ACCE_MASK, },
195 { .reg_offset = 1, .mask = SM5502_IRQ_INT2_ADC_CHG_MASK, },
196 { .reg_offset = 1, .mask = SM5502_IRQ_INT2_STUCK_KEY_MASK, },
197 { .reg_offset = 1, .mask = SM5502_IRQ_INT2_STUCK_KEY_RCV_MASK, },
198 { .reg_offset = 1, .mask = SM5502_IRQ_INT2_MHL_MASK, },
199};
200
201static const struct regmap_irq_chip sm5502_muic_irq_chip = {
202 .name = "sm5502",
203 .status_base = SM5502_REG_INT1,
204 .mask_base = SM5502_REG_INTMASK1,
205 .mask_invert = false,
206 .num_regs = 2,
207 .irqs = sm5502_irqs,
208 .num_irqs = ARRAY_SIZE(sm5502_irqs),
209};
210
211/* Define regmap configuration of SM5502 for I2C communication */
212static bool sm5502_muic_volatile_reg(struct device *dev, unsigned int reg)
213{
214 switch (reg) {
215 case SM5502_REG_INTMASK1:
216 case SM5502_REG_INTMASK2:
217 return true;
218 default:
219 break;
220 }
221 return false;
222}
223
224static const struct regmap_config sm5502_muic_regmap_config = {
225 .reg_bits = 8,
226 .val_bits = 8,
227 .volatile_reg = sm5502_muic_volatile_reg,
228 .max_register = SM5502_REG_END,
229};
230
231/* Change DM_CON/DP_CON/VBUSIN switch according to cable type */
232static int sm5502_muic_set_path(struct sm5502_muic_info *info,
233 unsigned int con_sw, unsigned int vbus_sw,
234 bool attached)
235{
236 int ret;
237
238 if (!attached) {
239 con_sw = DM_DP_SWITCH_OPEN;
240 vbus_sw = VBUSIN_SWITCH_OPEN;
241 }
242
243 switch (con_sw) {
244 case DM_DP_SWITCH_OPEN:
245 case DM_DP_SWITCH_USB:
246 case DM_DP_SWITCH_AUDIO:
247 case DM_DP_SWITCH_UART:
248 ret = regmap_update_bits(info->regmap, SM5502_REG_MANUAL_SW1,
249 SM5502_REG_MANUAL_SW1_DP_MASK |
250 SM5502_REG_MANUAL_SW1_DM_MASK,
251 con_sw);
252 if (ret < 0) {
253 dev_err(info->dev,
254 "cannot update DM_CON/DP_CON switch\n");
255 return ret;
256 }
257 break;
258 default:
259 dev_err(info->dev, "Unknown DM_CON/DP_CON switch type (%d)\n",
260 con_sw);
261 return -EINVAL;
262 };
263
264 switch (vbus_sw) {
265 case VBUSIN_SWITCH_OPEN:
266 case VBUSIN_SWITCH_VBUSOUT:
267 case VBUSIN_SWITCH_MIC:
268 case VBUSIN_SWITCH_VBUSOUT_WITH_USB:
269 ret = regmap_update_bits(info->regmap, SM5502_REG_MANUAL_SW1,
270 SM5502_REG_MANUAL_SW1_VBUSIN_MASK,
271 vbus_sw);
272 if (ret < 0) {
273 dev_err(info->dev,
274 "cannot update VBUSIN switch\n");
275 return ret;
276 }
277 break;
278 default:
279 dev_err(info->dev, "Unknown VBUS switch type (%d)\n", vbus_sw);
280 return -EINVAL;
281 };
282
283 return 0;
284}
285
286/* Return cable type of attached or detached accessories */
287static unsigned int sm5502_muic_get_cable_type(struct sm5502_muic_info *info)
288{
289 unsigned int cable_type = -1, adc, dev_type1;
290 int ret;
291
292 /* Read ADC value according to external cable or button */
293 ret = regmap_read(info->regmap, SM5502_REG_ADC, &adc);
294 if (ret) {
295 dev_err(info->dev, "failed to read ADC register\n");
296 return ret;
297 }
298
299 /*
300 * If ADC is SM5502_MUIC_ADC_GROUND(0x0), external cable hasn't
301 * connected with to MUIC device.
302 */
303 cable_type &= SM5502_REG_ADC_MASK;
304 if (cable_type == SM5502_MUIC_ADC_GROUND)
305 return SM5502_MUIC_ADC_GROUND;
306
307 switch (cable_type) {
308 case SM5502_MUIC_ADC_GROUND:
309 case SM5502_MUIC_ADC_SEND_END_BUTTON:
310 case SM5502_MUIC_ADC_REMOTE_S1_BUTTON:
311 case SM5502_MUIC_ADC_REMOTE_S2_BUTTON:
312 case SM5502_MUIC_ADC_REMOTE_S3_BUTTON:
313 case SM5502_MUIC_ADC_REMOTE_S4_BUTTON:
314 case SM5502_MUIC_ADC_REMOTE_S5_BUTTON:
315 case SM5502_MUIC_ADC_REMOTE_S6_BUTTON:
316 case SM5502_MUIC_ADC_REMOTE_S7_BUTTON:
317 case SM5502_MUIC_ADC_REMOTE_S8_BUTTON:
318 case SM5502_MUIC_ADC_REMOTE_S9_BUTTON:
319 case SM5502_MUIC_ADC_REMOTE_S10_BUTTON:
320 case SM5502_MUIC_ADC_REMOTE_S11_BUTTON:
321 case SM5502_MUIC_ADC_REMOTE_S12_BUTTON:
322 case SM5502_MUIC_ADC_RESERVED_ACC_1:
323 case SM5502_MUIC_ADC_RESERVED_ACC_2:
324 case SM5502_MUIC_ADC_RESERVED_ACC_3:
325 case SM5502_MUIC_ADC_RESERVED_ACC_4:
326 case SM5502_MUIC_ADC_RESERVED_ACC_5:
327 case SM5502_MUIC_ADC_AUDIO_TYPE2:
328 case SM5502_MUIC_ADC_PHONE_POWERED_DEV:
329 case SM5502_MUIC_ADC_TTY_CONVERTER:
330 case SM5502_MUIC_ADC_UART_CABLE:
331 case SM5502_MUIC_ADC_TYPE1_CHARGER:
332 case SM5502_MUIC_ADC_FACTORY_MODE_BOOT_OFF_USB:
333 case SM5502_MUIC_ADC_FACTORY_MODE_BOOT_ON_USB:
334 case SM5502_MUIC_ADC_AUDIO_VIDEO_CABLE:
335 case SM5502_MUIC_ADC_TYPE2_CHARGER:
336 case SM5502_MUIC_ADC_FACTORY_MODE_BOOT_OFF_UART:
337 case SM5502_MUIC_ADC_FACTORY_MODE_BOOT_ON_UART:
338 break;
339 case SM5502_MUIC_ADC_AUDIO_TYPE1:
340 /*
341 * Check whether cable type is
342 * SM5502_MUIC_ADC_AUDIO_TYPE1_FULL_REMOTE
343 * or SM5502_MUIC_ADC_AUDIO_TYPE1_SEND_END
344 * by using Button event.
345 */
346 break;
347 case SM5502_MUIC_ADC_OPEN:
348 ret = regmap_read(info->regmap, SM5502_REG_DEV_TYPE1,
349 &dev_type1);
350 if (ret) {
351 dev_err(info->dev, "failed to read DEV_TYPE1 reg\n");
352 return ret;
353 }
354
355 switch (dev_type1) {
356 case SM5502_REG_DEV_TYPE1_USB_SDP_MASK:
357 cable_type = SM5502_MUIC_ADC_OPEN_USB;
358 break;
359 case SM5502_REG_DEV_TYPE1_DEDICATED_CHG_MASK:
360 cable_type = SM5502_MUIC_ADC_OPEN_TA;
361 break;
362 case SM5502_REG_DEV_TYPE1_USB_OTG_MASK:
363 cable_type = SM5502_MUIC_ADC_OPEN_USB_OTG;
364 break;
365 default:
366 dev_dbg(info->dev,
367 "cannot identify the cable type: adc(0x%x) "
368 "dev_type1(0x%x)\n", adc, dev_type1);
369 return -EINVAL;
370 };
371 break;
372 default:
373 dev_err(info->dev,
374 "failed to identify the cable type: adc(0x%x)\n", adc);
375 return -EINVAL;
376 };
377
378 return cable_type;
379}
380
381static int sm5502_muic_cable_handler(struct sm5502_muic_info *info,
382 bool attached)
383{
384 static unsigned int prev_cable_type = SM5502_MUIC_ADC_GROUND;
385 const char **cable_names = info->edev->supported_cable;
386 unsigned int cable_type = SM5502_MUIC_ADC_GROUND;
387 unsigned int con_sw = DM_DP_SWITCH_OPEN;
388 unsigned int vbus_sw = VBUSIN_SWITCH_OPEN;
389 unsigned int idx = 0;
390 int ret;
391
392 if (!cable_names)
393 return 0;
394
395 /* Get the type of attached or detached cable */
396 if (attached)
397 cable_type = sm5502_muic_get_cable_type(info);
398 else if (!attached)
399 cable_type = prev_cable_type;
400 prev_cable_type = cable_type;
401
402 switch (cable_type) {
403 case SM5502_MUIC_ADC_OPEN_USB:
404 idx = EXTCON_CABLE_USB;
405 con_sw = DM_DP_SWITCH_USB;
406 vbus_sw = VBUSIN_SWITCH_VBUSOUT_WITH_USB;
407 break;
408 case SM5502_MUIC_ADC_OPEN_TA:
409 idx = EXTCON_CABLE_TA;
410 con_sw = DM_DP_SWITCH_OPEN;
411 vbus_sw = VBUSIN_SWITCH_VBUSOUT;
412 break;
413 case SM5502_MUIC_ADC_OPEN_USB_OTG:
414 idx = EXTCON_CABLE_USB_HOST;
415 con_sw = DM_DP_SWITCH_USB;
416 vbus_sw = VBUSIN_SWITCH_OPEN;
417 break;
418 default:
419 dev_dbg(info->dev,
420 "cannot handle this cable_type (0x%x)\n", cable_type);
421 return 0;
422 };
423
424 /* Change internal hardware path(DM_CON/DP_CON, VBUSIN) */
425 ret = sm5502_muic_set_path(info, con_sw, vbus_sw, attached);
426 if (ret < 0)
427 return ret;
428
429 /* Change the state of external accessory */
430 extcon_set_cable_state(info->edev, cable_names[idx], attached);
431
432 return 0;
433}
434
435static void sm5502_muic_irq_work(struct work_struct *work)
436{
437 struct sm5502_muic_info *info = container_of(work,
438 struct sm5502_muic_info, irq_work);
439 int ret = 0;
440
441 if (!info->edev)
442 return;
443
444 mutex_lock(&info->mutex);
445
446 /* Detect attached or detached cables */
447 if (info->irq_attach) {
448 ret = sm5502_muic_cable_handler(info, true);
449 info->irq_attach = false;
450 }
451 if (info->irq_detach) {
452 ret = sm5502_muic_cable_handler(info, false);
453 info->irq_detach = false;
454 }
455
456 if (ret < 0)
457 dev_err(info->dev, "failed to handle MUIC interrupt\n");
458
459 mutex_unlock(&info->mutex);
460
461 return;
462}
463
464/*
465 * Sets irq_attach or irq_detach in sm5502_muic_info and returns 0.
466 * Returns -ESRCH if irq_type does not match registered IRQ for this dev type.
467 */
468static int sm5502_parse_irq(struct sm5502_muic_info *info, int irq_type)
469{
470 switch (irq_type) {
471 case SM5502_IRQ_INT1_ATTACH:
472 info->irq_attach = true;
473 break;
474 case SM5502_IRQ_INT1_DETACH:
475 info->irq_detach = true;
476 break;
477 case SM5502_IRQ_INT1_KP:
478 case SM5502_IRQ_INT1_LKP:
479 case SM5502_IRQ_INT1_LKR:
480 case SM5502_IRQ_INT1_OVP_EVENT:
481 case SM5502_IRQ_INT1_OCP_EVENT:
482 case SM5502_IRQ_INT1_OVP_OCP_DIS:
483 case SM5502_IRQ_INT2_VBUS_DET:
484 case SM5502_IRQ_INT2_REV_ACCE:
485 case SM5502_IRQ_INT2_ADC_CHG:
486 case SM5502_IRQ_INT2_STUCK_KEY:
487 case SM5502_IRQ_INT2_STUCK_KEY_RCV:
488 case SM5502_IRQ_INT2_MHL:
489 default:
490 break;
491 }
492
493 return 0;
494}
495
496static irqreturn_t sm5502_muic_irq_handler(int irq, void *data)
497{
498 struct sm5502_muic_info *info = data;
499 int i, irq_type = -1, ret;
500
501 for (i = 0; i < info->num_muic_irqs; i++)
502 if (irq == info->muic_irqs[i].virq)
503 irq_type = info->muic_irqs[i].irq;
504
505 ret = sm5502_parse_irq(info, irq_type);
506 if (ret < 0) {
507 dev_warn(info->dev, "cannot handle is interrupt:%d\n",
508 irq_type);
509 return IRQ_HANDLED;
510 }
511 schedule_work(&info->irq_work);
512
513 return IRQ_HANDLED;
514}
515
516static void sm5502_muic_detect_cable_wq(struct work_struct *work)
517{
518 struct sm5502_muic_info *info = container_of(to_delayed_work(work),
519 struct sm5502_muic_info, wq_detcable);
520 int ret;
521
522 /* Notify the state of connector cable or not */
523 ret = sm5502_muic_cable_handler(info, true);
524 if (ret < 0)
525 dev_warn(info->dev, "failed to detect cable state\n");
526}
527
528static void sm5502_init_dev_type(struct sm5502_muic_info *info)
529{
530 unsigned int reg_data, vendor_id, version_id;
531 int i, ret;
532
533 /* To test I2C, Print version_id and vendor_id of SM5502 */
534 ret = regmap_read(info->regmap, SM5502_REG_DEVICE_ID, &reg_data);
535 if (ret) {
536 dev_err(info->dev,
537 "failed to read DEVICE_ID register: %d\n", ret);
538 return;
539 }
540
541 vendor_id = ((reg_data & SM5502_REG_DEVICE_ID_VENDOR_MASK) >>
542 SM5502_REG_DEVICE_ID_VENDOR_SHIFT);
543 version_id = ((reg_data & SM5502_REG_DEVICE_ID_VERSION_MASK) >>
544 SM5502_REG_DEVICE_ID_VERSION_SHIFT);
545
546 dev_info(info->dev, "Device type: version: 0x%x, vendor: 0x%x\n",
547 version_id, vendor_id);
548
549 /* Initiazle the register of SM5502 device to bring-up */
550 for (i = 0; i < info->num_reg_data; i++) {
551 unsigned int val = 0;
552
553 if (!info->reg_data[i].invert)
554 val |= ~info->reg_data[i].val;
555 else
556 val = info->reg_data[i].val;
557 regmap_write(info->regmap, info->reg_data[i].reg, val);
558 }
559}
560
561static int sm5022_muic_i2c_probe(struct i2c_client *i2c,
562 const struct i2c_device_id *id)
563{
564 struct device_node *np = i2c->dev.of_node;
565 struct sm5502_muic_info *info;
566 int i, ret, irq_flags;
567
568 if (!np)
569 return -EINVAL;
570
571 info = devm_kzalloc(&i2c->dev, sizeof(*info), GFP_KERNEL);
572 if (!info)
573 return -ENOMEM;
574 i2c_set_clientdata(i2c, info);
575
576 info->dev = &i2c->dev;
577 info->i2c = i2c;
578 info->irq = i2c->irq;
579 info->muic_irqs = sm5502_muic_irqs;
580 info->num_muic_irqs = ARRAY_SIZE(sm5502_muic_irqs);
581 info->reg_data = sm5502_reg_data;
582 info->num_reg_data = ARRAY_SIZE(sm5502_reg_data);
583
584 mutex_init(&info->mutex);
585
586 INIT_WORK(&info->irq_work, sm5502_muic_irq_work);
587
588 info->regmap = devm_regmap_init_i2c(i2c, &sm5502_muic_regmap_config);
589 if (IS_ERR(info->regmap)) {
590 ret = PTR_ERR(info->regmap);
591 dev_err(info->dev, "failed to allocate register map: %d\n",
592 ret);
593 return ret;
594 }
595
596 /* Support irq domain for SM5502 MUIC device */
597 irq_flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT | IRQF_SHARED;
598 ret = regmap_add_irq_chip(info->regmap, info->irq, irq_flags, 0,
599 &sm5502_muic_irq_chip, &info->irq_data);
600 if (ret != 0) {
601 dev_err(info->dev, "failed to request IRQ %d: %d\n",
602 info->irq, ret);
603 return ret;
604 }
605
606 for (i = 0; i < info->num_muic_irqs; i++) {
607 struct muic_irq *muic_irq = &info->muic_irqs[i];
608 unsigned int virq = 0;
609
610 virq = regmap_irq_get_virq(info->irq_data, muic_irq->irq);
611 if (virq <= 0)
612 return -EINVAL;
613 muic_irq->virq = virq;
614
615 ret = devm_request_threaded_irq(info->dev, virq, NULL,
616 sm5502_muic_irq_handler,
617 IRQF_NO_SUSPEND,
618 muic_irq->name, info);
619 if (ret) {
620 dev_err(info->dev, "failed: irq request (IRQ: %d,"
621 " error :%d)\n", muic_irq->irq, ret);
622 return ret;
623 }
624 }
625
626 /* Allocate extcon device */
627 info->edev = devm_extcon_dev_allocate(info->dev, sm5502_extcon_cable);
628 if (IS_ERR(info->edev)) {
629 dev_err(info->dev, "failed to allocate memory for extcon\n");
630 return -ENOMEM;
631 }
632 info->edev->name = np->name;
633
634 /* Register extcon device */
635 ret = devm_extcon_dev_register(info->dev, info->edev);
636 if (ret) {
637 dev_err(info->dev, "failed to register extcon device\n");
638 return ret;
639 }
640
641 /*
642 * Detect accessory after completing the initialization of platform
643 *
644 * - Use delayed workqueue to detect cable state and then
645 * notify cable state to notifiee/platform through uevent.
646 * After completing the booting of platform, the extcon provider
647 * driver should notify cable state to upper layer.
648 */
649 INIT_DELAYED_WORK(&info->wq_detcable, sm5502_muic_detect_cable_wq);
650 queue_delayed_work(system_power_efficient_wq, &info->wq_detcable,
651 msecs_to_jiffies(DELAY_MS_DEFAULT));
652
653 /* Initialize SM5502 device and print vendor id and version id */
654 sm5502_init_dev_type(info);
655
656 return 0;
657}
658
659static int sm5502_muic_i2c_remove(struct i2c_client *i2c)
660{
661 struct sm5502_muic_info *info = i2c_get_clientdata(i2c);
662
663 regmap_del_irq_chip(info->irq, info->irq_data);
664
665 return 0;
666}
667
668static struct of_device_id sm5502_dt_match[] = {
669 { .compatible = "siliconmitus,sm5502-muic" },
670 { },
671};
672
673#ifdef CONFIG_PM_SLEEP
674static int sm5502_muic_suspend(struct device *dev)
675{
676 struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
677 struct sm5502_muic_info *info = i2c_get_clientdata(i2c);
678
679 enable_irq_wake(info->irq);
680
681 return 0;
682}
683
684static int sm5502_muic_resume(struct device *dev)
685{
686 struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
687 struct sm5502_muic_info *info = i2c_get_clientdata(i2c);
688
689 disable_irq_wake(info->irq);
690
691 return 0;
692}
693#endif
694
695static SIMPLE_DEV_PM_OPS(sm5502_muic_pm_ops,
696 sm5502_muic_suspend, sm5502_muic_resume);
697
698static const struct i2c_device_id sm5502_i2c_id[] = {
699 { "sm5502", TYPE_SM5502 },
700 { }
701};
702MODULE_DEVICE_TABLE(i2c, sm5502_i2c_id);
703
704static struct i2c_driver sm5502_muic_i2c_driver = {
705 .driver = {
706 .name = "sm5502",
707 .owner = THIS_MODULE,
708 .pm = &sm5502_muic_pm_ops,
709 .of_match_table = sm5502_dt_match,
710 },
711 .probe = sm5022_muic_i2c_probe,
712 .remove = sm5502_muic_i2c_remove,
713 .id_table = sm5502_i2c_id,
714};
715
716static int __init sm5502_muic_i2c_init(void)
717{
718 return i2c_add_driver(&sm5502_muic_i2c_driver);
719}
720subsys_initcall(sm5502_muic_i2c_init);
721
722MODULE_DESCRIPTION("Silicon Mitus SM5502 Extcon driver");
723MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
724MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 6cc4b6acc22a..fb824f501197 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -384,6 +384,7 @@ config MFD_MAX77693
384 depends on I2C=y 384 depends on I2C=y
385 select MFD_CORE 385 select MFD_CORE
386 select REGMAP_I2C 386 select REGMAP_I2C
387 select REGMAP_IRQ
387 help 388 help
388 Say yes here to add support for Maxim Semiconductor MAX77693. 389 Say yes here to add support for Maxim Semiconductor MAX77693.
389 This is a companion Power Management IC with Flash, Haptic, Charger, 390 This is a companion Power Management IC with Flash, Haptic, Charger,
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 8afedba535c7..8c6e7bba4660 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -116,7 +116,7 @@ obj-$(CONFIG_MFD_DA9063) += da9063.o
116 116
117obj-$(CONFIG_MFD_MAX14577) += max14577.o 117obj-$(CONFIG_MFD_MAX14577) += max14577.o
118obj-$(CONFIG_MFD_MAX77686) += max77686.o max77686-irq.o 118obj-$(CONFIG_MFD_MAX77686) += max77686.o max77686-irq.o
119obj-$(CONFIG_MFD_MAX77693) += max77693.o max77693-irq.o 119obj-$(CONFIG_MFD_MAX77693) += max77693.o
120obj-$(CONFIG_MFD_MAX8907) += max8907.o 120obj-$(CONFIG_MFD_MAX8907) += max8907.o
121max8925-objs := max8925-core.o max8925-i2c.o 121max8925-objs := max8925-core.o max8925-i2c.o
122obj-$(CONFIG_MFD_MAX8925) += max8925.o 122obj-$(CONFIG_MFD_MAX8925) += max8925.o
diff --git a/drivers/mfd/max77693-irq.c b/drivers/mfd/max77693-irq.c
deleted file mode 100644
index 66b58fe77094..000000000000
--- a/drivers/mfd/max77693-irq.c
+++ /dev/null
@@ -1,336 +0,0 @@
1/*
2 * max77693-irq.c - Interrupt controller support for MAX77693
3 *
4 * Copyright (C) 2012 Samsung Electronics Co.Ltd
5 * SangYoung Son <hello.son@samsung.com>
6 *
7 * This program is not provided / owned by Maxim Integrated Products.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 * This driver is based on max8997-irq.c
24 */
25
26#include <linux/err.h>
27#include <linux/irq.h>
28#include <linux/interrupt.h>
29#include <linux/module.h>
30#include <linux/irqdomain.h>
31#include <linux/mfd/max77693.h>
32#include <linux/mfd/max77693-private.h>
33
34static const u8 max77693_mask_reg[] = {
35 [LED_INT] = MAX77693_LED_REG_FLASH_INT_MASK,
36 [TOPSYS_INT] = MAX77693_PMIC_REG_TOPSYS_INT_MASK,
37 [CHG_INT] = MAX77693_CHG_REG_CHG_INT_MASK,
38 [MUIC_INT1] = MAX77693_MUIC_REG_INTMASK1,
39 [MUIC_INT2] = MAX77693_MUIC_REG_INTMASK2,
40 [MUIC_INT3] = MAX77693_MUIC_REG_INTMASK3,
41};
42
43static struct regmap *max77693_get_regmap(struct max77693_dev *max77693,
44 enum max77693_irq_source src)
45{
46 switch (src) {
47 case LED_INT ... CHG_INT:
48 return max77693->regmap;
49 case MUIC_INT1 ... MUIC_INT3:
50 return max77693->regmap_muic;
51 default:
52 return ERR_PTR(-EINVAL);
53 }
54}
55
56struct max77693_irq_data {
57 int mask;
58 enum max77693_irq_source group;
59};
60
61#define DECLARE_IRQ(idx, _group, _mask) \
62 [(idx)] = { .group = (_group), .mask = (_mask) }
63static const struct max77693_irq_data max77693_irqs[] = {
64 DECLARE_IRQ(MAX77693_LED_IRQ_FLED2_OPEN, LED_INT, 1 << 0),
65 DECLARE_IRQ(MAX77693_LED_IRQ_FLED2_SHORT, LED_INT, 1 << 1),
66 DECLARE_IRQ(MAX77693_LED_IRQ_FLED1_OPEN, LED_INT, 1 << 2),
67 DECLARE_IRQ(MAX77693_LED_IRQ_FLED1_SHORT, LED_INT, 1 << 3),
68 DECLARE_IRQ(MAX77693_LED_IRQ_MAX_FLASH, LED_INT, 1 << 4),
69
70 DECLARE_IRQ(MAX77693_TOPSYS_IRQ_T120C_INT, TOPSYS_INT, 1 << 0),
71 DECLARE_IRQ(MAX77693_TOPSYS_IRQ_T140C_INT, TOPSYS_INT, 1 << 1),
72 DECLARE_IRQ(MAX77693_TOPSYS_IRQ_LOWSYS_INT, TOPSYS_INT, 1 << 3),
73
74 DECLARE_IRQ(MAX77693_CHG_IRQ_BYP_I, CHG_INT, 1 << 0),
75 DECLARE_IRQ(MAX77693_CHG_IRQ_THM_I, CHG_INT, 1 << 2),
76 DECLARE_IRQ(MAX77693_CHG_IRQ_BAT_I, CHG_INT, 1 << 3),
77 DECLARE_IRQ(MAX77693_CHG_IRQ_CHG_I, CHG_INT, 1 << 4),
78 DECLARE_IRQ(MAX77693_CHG_IRQ_CHGIN_I, CHG_INT, 1 << 6),
79
80 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC, MUIC_INT1, 1 << 0),
81 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC_LOW, MUIC_INT1, 1 << 1),
82 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC_ERR, MUIC_INT1, 1 << 2),
83 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT1_ADC1K, MUIC_INT1, 1 << 3),
84
85 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_CHGTYP, MUIC_INT2, 1 << 0),
86 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_CHGDETREUN, MUIC_INT2, 1 << 1),
87 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_DCDTMR, MUIC_INT2, 1 << 2),
88 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_DXOVP, MUIC_INT2, 1 << 3),
89 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_VBVOLT, MUIC_INT2, 1 << 4),
90 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT2_VIDRM, MUIC_INT2, 1 << 5),
91
92 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_EOC, MUIC_INT3, 1 << 0),
93 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_CGMBC, MUIC_INT3, 1 << 1),
94 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_OVP, MUIC_INT3, 1 << 2),
95 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_MBCCHG_ERR, MUIC_INT3, 1 << 3),
96 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_CHG_ENABLED, MUIC_INT3, 1 << 4),
97 DECLARE_IRQ(MAX77693_MUIC_IRQ_INT3_BAT_DET, MUIC_INT3, 1 << 5),
98};
99
100static void max77693_irq_lock(struct irq_data *data)
101{
102 struct max77693_dev *max77693 = irq_get_chip_data(data->irq);
103
104 mutex_lock(&max77693->irqlock);
105}
106
107static void max77693_irq_sync_unlock(struct irq_data *data)
108{
109 struct max77693_dev *max77693 = irq_get_chip_data(data->irq);
110 int i;
111
112 for (i = 0; i < MAX77693_IRQ_GROUP_NR; i++) {
113 u8 mask_reg = max77693_mask_reg[i];
114 struct regmap *map = max77693_get_regmap(max77693, i);
115
116 if (mask_reg == MAX77693_REG_INVALID ||
117 IS_ERR_OR_NULL(map))
118 continue;
119 max77693->irq_masks_cache[i] = max77693->irq_masks_cur[i];
120
121 max77693_write_reg(map, max77693_mask_reg[i],
122 max77693->irq_masks_cur[i]);
123 }
124
125 mutex_unlock(&max77693->irqlock);
126}
127
128static const inline struct max77693_irq_data *
129irq_to_max77693_irq(struct max77693_dev *max77693, int irq)
130{
131 struct irq_data *data = irq_get_irq_data(irq);
132 return &max77693_irqs[data->hwirq];
133}
134
135static void max77693_irq_mask(struct irq_data *data)
136{
137 struct max77693_dev *max77693 = irq_get_chip_data(data->irq);
138 const struct max77693_irq_data *irq_data =
139 irq_to_max77693_irq(max77693, data->irq);
140
141 if (irq_data->group >= MAX77693_IRQ_GROUP_NR)
142 return;
143
144 if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3)
145 max77693->irq_masks_cur[irq_data->group] &= ~irq_data->mask;
146 else
147 max77693->irq_masks_cur[irq_data->group] |= irq_data->mask;
148}
149
150static void max77693_irq_unmask(struct irq_data *data)
151{
152 struct max77693_dev *max77693 = irq_get_chip_data(data->irq);
153 const struct max77693_irq_data *irq_data =
154 irq_to_max77693_irq(max77693, data->irq);
155
156 if (irq_data->group >= MAX77693_IRQ_GROUP_NR)
157 return;
158
159 if (irq_data->group >= MUIC_INT1 && irq_data->group <= MUIC_INT3)
160 max77693->irq_masks_cur[irq_data->group] |= irq_data->mask;
161 else
162 max77693->irq_masks_cur[irq_data->group] &= ~irq_data->mask;
163}
164
165static struct irq_chip max77693_irq_chip = {
166 .name = "max77693",
167 .irq_bus_lock = max77693_irq_lock,
168 .irq_bus_sync_unlock = max77693_irq_sync_unlock,
169 .irq_mask = max77693_irq_mask,
170 .irq_unmask = max77693_irq_unmask,
171};
172
173#define MAX77693_IRQSRC_CHG (1 << 0)
174#define MAX77693_IRQSRC_TOP (1 << 1)
175#define MAX77693_IRQSRC_FLASH (1 << 2)
176#define MAX77693_IRQSRC_MUIC (1 << 3)
177static irqreturn_t max77693_irq_thread(int irq, void *data)
178{
179 struct max77693_dev *max77693 = data;
180 u8 irq_reg[MAX77693_IRQ_GROUP_NR] = {};
181 u8 irq_src;
182 int ret;
183 int i, cur_irq;
184
185 ret = max77693_read_reg(max77693->regmap, MAX77693_PMIC_REG_INTSRC,
186 &irq_src);
187 if (ret < 0) {
188 dev_err(max77693->dev, "Failed to read interrupt source: %d\n",
189 ret);
190 return IRQ_NONE;
191 }
192
193 if (irq_src & MAX77693_IRQSRC_CHG)
194 /* CHG_INT */
195 ret = max77693_read_reg(max77693->regmap, MAX77693_CHG_REG_CHG_INT,
196 &irq_reg[CHG_INT]);
197
198 if (irq_src & MAX77693_IRQSRC_TOP)
199 /* TOPSYS_INT */
200 ret = max77693_read_reg(max77693->regmap,
201 MAX77693_PMIC_REG_TOPSYS_INT, &irq_reg[TOPSYS_INT]);
202
203 if (irq_src & MAX77693_IRQSRC_FLASH)
204 /* LED_INT */
205 ret = max77693_read_reg(max77693->regmap,
206 MAX77693_LED_REG_FLASH_INT, &irq_reg[LED_INT]);
207
208 if (irq_src & MAX77693_IRQSRC_MUIC)
209 /* MUIC INT1 ~ INT3 */
210 max77693_bulk_read(max77693->regmap_muic, MAX77693_MUIC_REG_INT1,
211 MAX77693_NUM_IRQ_MUIC_REGS, &irq_reg[MUIC_INT1]);
212
213 /* Apply masking */
214 for (i = 0; i < MAX77693_IRQ_GROUP_NR; i++) {
215 if (i >= MUIC_INT1 && i <= MUIC_INT3)
216 irq_reg[i] &= max77693->irq_masks_cur[i];
217 else
218 irq_reg[i] &= ~max77693->irq_masks_cur[i];
219 }
220
221 /* Report */
222 for (i = 0; i < MAX77693_IRQ_NR; i++) {
223 if (irq_reg[max77693_irqs[i].group] & max77693_irqs[i].mask) {
224 cur_irq = irq_find_mapping(max77693->irq_domain, i);
225 if (cur_irq)
226 handle_nested_irq(cur_irq);
227 }
228 }
229
230 return IRQ_HANDLED;
231}
232
233int max77693_irq_resume(struct max77693_dev *max77693)
234{
235 if (max77693->irq)
236 max77693_irq_thread(0, max77693);
237
238 return 0;
239}
240
241static int max77693_irq_domain_map(struct irq_domain *d, unsigned int irq,
242 irq_hw_number_t hw)
243{
244 struct max77693_dev *max77693 = d->host_data;
245
246 irq_set_chip_data(irq, max77693);
247 irq_set_chip_and_handler(irq, &max77693_irq_chip, handle_edge_irq);
248 irq_set_nested_thread(irq, 1);
249#ifdef CONFIG_ARM
250 set_irq_flags(irq, IRQF_VALID);
251#else
252 irq_set_noprobe(irq);
253#endif
254 return 0;
255}
256
257static struct irq_domain_ops max77693_irq_domain_ops = {
258 .map = max77693_irq_domain_map,
259};
260
261int max77693_irq_init(struct max77693_dev *max77693)
262{
263 struct irq_domain *domain;
264 int i;
265 int ret = 0;
266 u8 intsrc_mask;
267
268 mutex_init(&max77693->irqlock);
269
270 /* Mask individual interrupt sources */
271 for (i = 0; i < MAX77693_IRQ_GROUP_NR; i++) {
272 struct regmap *map;
273 /* MUIC IRQ 0:MASK 1:NOT MASK */
274 /* Other IRQ 1:MASK 0:NOT MASK */
275 if (i >= MUIC_INT1 && i <= MUIC_INT3) {
276 max77693->irq_masks_cur[i] = 0x00;
277 max77693->irq_masks_cache[i] = 0x00;
278 } else {
279 max77693->irq_masks_cur[i] = 0xff;
280 max77693->irq_masks_cache[i] = 0xff;
281 }
282 map = max77693_get_regmap(max77693, i);
283
284 if (IS_ERR_OR_NULL(map))
285 continue;
286 if (max77693_mask_reg[i] == MAX77693_REG_INVALID)
287 continue;
288 if (i >= MUIC_INT1 && i <= MUIC_INT3)
289 max77693_write_reg(map, max77693_mask_reg[i], 0x00);
290 else
291 max77693_write_reg(map, max77693_mask_reg[i], 0xff);
292 }
293
294 domain = irq_domain_add_linear(NULL, MAX77693_IRQ_NR,
295 &max77693_irq_domain_ops, max77693);
296 if (!domain) {
297 dev_err(max77693->dev, "could not create irq domain\n");
298 ret = -ENODEV;
299 goto err_irq;
300 }
301 max77693->irq_domain = domain;
302
303 /* Unmask max77693 interrupt */
304 ret = max77693_read_reg(max77693->regmap,
305 MAX77693_PMIC_REG_INTSRC_MASK, &intsrc_mask);
306 if (ret < 0) {
307 dev_err(max77693->dev, "fail to read PMIC register\n");
308 goto err_irq;
309 }
310
311 intsrc_mask &= ~(MAX77693_IRQSRC_CHG);
312 intsrc_mask &= ~(MAX77693_IRQSRC_FLASH);
313 intsrc_mask &= ~(MAX77693_IRQSRC_MUIC);
314 ret = max77693_write_reg(max77693->regmap,
315 MAX77693_PMIC_REG_INTSRC_MASK, intsrc_mask);
316 if (ret < 0) {
317 dev_err(max77693->dev, "fail to write PMIC register\n");
318 goto err_irq;
319 }
320
321 ret = request_threaded_irq(max77693->irq, NULL, max77693_irq_thread,
322 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
323 "max77693-irq", max77693);
324 if (ret)
325 dev_err(max77693->dev, "Failed to request IRQ %d: %d\n",
326 max77693->irq, ret);
327
328err_irq:
329 return ret;
330}
331
332void max77693_irq_exit(struct max77693_dev *max77693)
333{
334 if (max77693->irq)
335 free_irq(max77693->irq, max77693);
336}
diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c
index 7e05428c756d..249c139ef04a 100644
--- a/drivers/mfd/max77693.c
+++ b/drivers/mfd/max77693.c
@@ -49,62 +49,62 @@ static const struct mfd_cell max77693_devs[] = {
49 { .name = "max77693-haptic", }, 49 { .name = "max77693-haptic", },
50}; 50};
51 51
52int max77693_read_reg(struct regmap *map, u8 reg, u8 *dest) 52static const struct regmap_config max77693_regmap_config = {
53{ 53 .reg_bits = 8,
54 unsigned int val; 54 .val_bits = 8,
55 int ret; 55 .max_register = MAX77693_PMIC_REG_END,
56 56};
57 ret = regmap_read(map, reg, &val);
58 *dest = val;
59
60 return ret;
61}
62EXPORT_SYMBOL_GPL(max77693_read_reg);
63
64int max77693_bulk_read(struct regmap *map, u8 reg, int count, u8 *buf)
65{
66 int ret;
67
68 ret = regmap_bulk_read(map, reg, buf, count);
69
70 return ret;
71}
72EXPORT_SYMBOL_GPL(max77693_bulk_read);
73
74int max77693_write_reg(struct regmap *map, u8 reg, u8 value)
75{
76 int ret;
77
78 ret = regmap_write(map, reg, value);
79
80 return ret;
81}
82EXPORT_SYMBOL_GPL(max77693_write_reg);
83
84int max77693_bulk_write(struct regmap *map, u8 reg, int count, u8 *buf)
85{
86 int ret;
87 57
88 ret = regmap_bulk_write(map, reg, buf, count); 58static const struct regmap_irq max77693_led_irqs[] = {
59 { .mask = LED_IRQ_FLED2_OPEN, },
60 { .mask = LED_IRQ_FLED2_SHORT, },
61 { .mask = LED_IRQ_FLED1_OPEN, },
62 { .mask = LED_IRQ_FLED1_SHORT, },
63 { .mask = LED_IRQ_MAX_FLASH, },
64};
89 65
90 return ret; 66static const struct regmap_irq_chip max77693_led_irq_chip = {
91} 67 .name = "max77693-led",
92EXPORT_SYMBOL_GPL(max77693_bulk_write); 68 .status_base = MAX77693_LED_REG_FLASH_INT,
69 .mask_base = MAX77693_LED_REG_FLASH_INT_MASK,
70 .mask_invert = false,
71 .num_regs = 1,
72 .irqs = max77693_led_irqs,
73 .num_irqs = ARRAY_SIZE(max77693_led_irqs),
74};
93 75
94int max77693_update_reg(struct regmap *map, u8 reg, u8 val, u8 mask) 76static const struct regmap_irq max77693_topsys_irqs[] = {
95{ 77 { .mask = TOPSYS_IRQ_T120C_INT, },
96 int ret; 78 { .mask = TOPSYS_IRQ_T140C_INT, },
79 { .mask = TOPSYS_IRQ_LOWSYS_INT, },
80};
97 81
98 ret = regmap_update_bits(map, reg, mask, val); 82static const struct regmap_irq_chip max77693_topsys_irq_chip = {
83 .name = "max77693-topsys",
84 .status_base = MAX77693_PMIC_REG_TOPSYS_INT,
85 .mask_base = MAX77693_PMIC_REG_TOPSYS_INT_MASK,
86 .mask_invert = false,
87 .num_regs = 1,
88 .irqs = max77693_topsys_irqs,
89 .num_irqs = ARRAY_SIZE(max77693_topsys_irqs),
90};
99 91
100 return ret; 92static const struct regmap_irq max77693_charger_irqs[] = {
101} 93 { .mask = CHG_IRQ_BYP_I, },
102EXPORT_SYMBOL_GPL(max77693_update_reg); 94 { .mask = CHG_IRQ_THM_I, },
95 { .mask = CHG_IRQ_BAT_I, },
96 { .mask = CHG_IRQ_CHG_I, },
97 { .mask = CHG_IRQ_CHGIN_I, },
98};
103 99
104static const struct regmap_config max77693_regmap_config = { 100static const struct regmap_irq_chip max77693_charger_irq_chip = {
105 .reg_bits = 8, 101 .name = "max77693-charger",
106 .val_bits = 8, 102 .status_base = MAX77693_CHG_REG_CHG_INT,
107 .max_register = MAX77693_PMIC_REG_END, 103 .mask_base = MAX77693_CHG_REG_CHG_INT_MASK,
104 .mask_invert = false,
105 .num_regs = 1,
106 .irqs = max77693_charger_irqs,
107 .num_irqs = ARRAY_SIZE(max77693_charger_irqs),
108}; 108};
109 109
110static const struct regmap_config max77693_regmap_muic_config = { 110static const struct regmap_config max77693_regmap_muic_config = {
@@ -113,11 +113,42 @@ static const struct regmap_config max77693_regmap_muic_config = {
113 .max_register = MAX77693_MUIC_REG_END, 113 .max_register = MAX77693_MUIC_REG_END,
114}; 114};
115 115
116static const struct regmap_irq max77693_muic_irqs[] = {
117 { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC, },
118 { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC_LOW, },
119 { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC_ERR, },
120 { .reg_offset = 0, .mask = MUIC_IRQ_INT1_ADC1K, },
121
122 { .reg_offset = 1, .mask = MUIC_IRQ_INT2_CHGTYP, },
123 { .reg_offset = 1, .mask = MUIC_IRQ_INT2_CHGDETREUN, },
124 { .reg_offset = 1, .mask = MUIC_IRQ_INT2_DCDTMR, },
125 { .reg_offset = 1, .mask = MUIC_IRQ_INT2_DXOVP, },
126 { .reg_offset = 1, .mask = MUIC_IRQ_INT2_VBVOLT, },
127 { .reg_offset = 1, .mask = MUIC_IRQ_INT2_VIDRM, },
128
129 { .reg_offset = 2, .mask = MUIC_IRQ_INT3_EOC, },
130 { .reg_offset = 2, .mask = MUIC_IRQ_INT3_CGMBC, },
131 { .reg_offset = 2, .mask = MUIC_IRQ_INT3_OVP, },
132 { .reg_offset = 2, .mask = MUIC_IRQ_INT3_MBCCHG_ERR, },
133 { .reg_offset = 2, .mask = MUIC_IRQ_INT3_CHG_ENABLED, },
134 { .reg_offset = 2, .mask = MUIC_IRQ_INT3_BAT_DET, },
135};
136
137static const struct regmap_irq_chip max77693_muic_irq_chip = {
138 .name = "max77693-muic",
139 .status_base = MAX77693_MUIC_REG_INT1,
140 .mask_base = MAX77693_MUIC_REG_INTMASK1,
141 .mask_invert = true,
142 .num_regs = 3,
143 .irqs = max77693_muic_irqs,
144 .num_irqs = ARRAY_SIZE(max77693_muic_irqs),
145};
146
116static int max77693_i2c_probe(struct i2c_client *i2c, 147static int max77693_i2c_probe(struct i2c_client *i2c,
117 const struct i2c_device_id *id) 148 const struct i2c_device_id *id)
118{ 149{
119 struct max77693_dev *max77693; 150 struct max77693_dev *max77693;
120 u8 reg_data; 151 unsigned int reg_data;
121 int ret = 0; 152 int ret = 0;
122 153
123 max77693 = devm_kzalloc(&i2c->dev, 154 max77693 = devm_kzalloc(&i2c->dev,
@@ -139,7 +170,7 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
139 return ret; 170 return ret;
140 } 171 }
141 172
142 ret = max77693_read_reg(max77693->regmap, MAX77693_PMIC_REG_PMIC_ID2, 173 ret = regmap_read(max77693->regmap, MAX77693_PMIC_REG_PMIC_ID2,
143 &reg_data); 174 &reg_data);
144 if (ret < 0) { 175 if (ret < 0) {
145 dev_err(max77693->dev, "device not found on this channel\n"); 176 dev_err(max77693->dev, "device not found on this channel\n");
@@ -176,9 +207,45 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
176 goto err_regmap_muic; 207 goto err_regmap_muic;
177 } 208 }
178 209
179 ret = max77693_irq_init(max77693); 210 ret = regmap_add_irq_chip(max77693->regmap, max77693->irq,
180 if (ret < 0) 211 IRQF_ONESHOT | IRQF_SHARED |
181 goto err_irq; 212 IRQF_TRIGGER_FALLING, 0,
213 &max77693_led_irq_chip,
214 &max77693->irq_data_led);
215 if (ret) {
216 dev_err(max77693->dev, "failed to add irq chip: %d\n", ret);
217 goto err_regmap_muic;
218 }
219
220 ret = regmap_add_irq_chip(max77693->regmap, max77693->irq,
221 IRQF_ONESHOT | IRQF_SHARED |
222 IRQF_TRIGGER_FALLING, 0,
223 &max77693_topsys_irq_chip,
224 &max77693->irq_data_topsys);
225 if (ret) {
226 dev_err(max77693->dev, "failed to add irq chip: %d\n", ret);
227 goto err_irq_topsys;
228 }
229
230 ret = regmap_add_irq_chip(max77693->regmap, max77693->irq,
231 IRQF_ONESHOT | IRQF_SHARED |
232 IRQF_TRIGGER_FALLING, 0,
233 &max77693_charger_irq_chip,
234 &max77693->irq_data_charger);
235 if (ret) {
236 dev_err(max77693->dev, "failed to add irq chip: %d\n", ret);
237 goto err_irq_charger;
238 }
239
240 ret = regmap_add_irq_chip(max77693->regmap, max77693->irq,
241 IRQF_ONESHOT | IRQF_SHARED |
242 IRQF_TRIGGER_FALLING, 0,
243 &max77693_muic_irq_chip,
244 &max77693->irq_data_muic);
245 if (ret) {
246 dev_err(max77693->dev, "failed to add irq chip: %d\n", ret);
247 goto err_irq_muic;
248 }
182 249
183 pm_runtime_set_active(max77693->dev); 250 pm_runtime_set_active(max77693->dev);
184 251
@@ -190,8 +257,14 @@ static int max77693_i2c_probe(struct i2c_client *i2c,
190 return ret; 257 return ret;
191 258
192err_mfd: 259err_mfd:
193 max77693_irq_exit(max77693); 260 mfd_remove_devices(max77693->dev);
194err_irq: 261 regmap_del_irq_chip(max77693->irq, max77693->irq_data_muic);
262err_irq_muic:
263 regmap_del_irq_chip(max77693->irq, max77693->irq_data_charger);
264err_irq_charger:
265 regmap_del_irq_chip(max77693->irq, max77693->irq_data_topsys);
266err_irq_topsys:
267 regmap_del_irq_chip(max77693->irq, max77693->irq_data_led);
195err_regmap_muic: 268err_regmap_muic:
196 i2c_unregister_device(max77693->haptic); 269 i2c_unregister_device(max77693->haptic);
197err_i2c_haptic: 270err_i2c_haptic:
@@ -204,7 +277,12 @@ static int max77693_i2c_remove(struct i2c_client *i2c)
204 struct max77693_dev *max77693 = i2c_get_clientdata(i2c); 277 struct max77693_dev *max77693 = i2c_get_clientdata(i2c);
205 278
206 mfd_remove_devices(max77693->dev); 279 mfd_remove_devices(max77693->dev);
207 max77693_irq_exit(max77693); 280
281 regmap_del_irq_chip(max77693->irq, max77693->irq_data_muic);
282 regmap_del_irq_chip(max77693->irq, max77693->irq_data_charger);
283 regmap_del_irq_chip(max77693->irq, max77693->irq_data_topsys);
284 regmap_del_irq_chip(max77693->irq, max77693->irq_data_led);
285
208 i2c_unregister_device(max77693->muic); 286 i2c_unregister_device(max77693->muic);
209 i2c_unregister_device(max77693->haptic); 287 i2c_unregister_device(max77693->haptic);
210 288
@@ -222,8 +300,11 @@ static int max77693_suspend(struct device *dev)
222 struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); 300 struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
223 struct max77693_dev *max77693 = i2c_get_clientdata(i2c); 301 struct max77693_dev *max77693 = i2c_get_clientdata(i2c);
224 302
225 if (device_may_wakeup(dev)) 303 if (device_may_wakeup(dev)) {
226 irq_set_irq_wake(max77693->irq, 1); 304 enable_irq_wake(max77693->irq);
305 disable_irq(max77693->irq);
306 }
307
227 return 0; 308 return 0;
228} 309}
229 310
@@ -232,9 +313,12 @@ static int max77693_resume(struct device *dev)
232 struct i2c_client *i2c = container_of(dev, struct i2c_client, dev); 313 struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
233 struct max77693_dev *max77693 = i2c_get_clientdata(i2c); 314 struct max77693_dev *max77693 = i2c_get_clientdata(i2c);
234 315
235 if (device_may_wakeup(dev)) 316 if (device_may_wakeup(dev)) {
236 irq_set_irq_wake(max77693->irq, 0); 317 disable_irq_wake(max77693->irq);
237 return max77693_irq_resume(max77693); 318 enable_irq(max77693->irq);
319 }
320
321 return 0;
238} 322}
239 323
240static const struct dev_pm_ops max77693_pm = { 324static const struct dev_pm_ops max77693_pm = {
diff --git a/drivers/regulator/max77693.c b/drivers/regulator/max77693.c
index 653a58b49cdf..c67ff05fc1dd 100644
--- a/drivers/regulator/max77693.c
+++ b/drivers/regulator/max77693.c
@@ -31,6 +31,7 @@
31#include <linux/mfd/max77693.h> 31#include <linux/mfd/max77693.h>
32#include <linux/mfd/max77693-private.h> 32#include <linux/mfd/max77693-private.h>
33#include <linux/regulator/of_regulator.h> 33#include <linux/regulator/of_regulator.h>
34#include <linux/regmap.h>
34 35
35#define CHGIN_ILIM_STEP_20mA 20000 36#define CHGIN_ILIM_STEP_20mA 20000
36 37
@@ -39,9 +40,9 @@
39static int max77693_chg_is_enabled(struct regulator_dev *rdev) 40static int max77693_chg_is_enabled(struct regulator_dev *rdev)
40{ 41{
41 int ret; 42 int ret;
42 u8 val; 43 unsigned int val;
43 44
44 ret = max77693_read_reg(rdev->regmap, rdev->desc->enable_reg, &val); 45 ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val);
45 if (ret) 46 if (ret)
46 return ret; 47 return ret;
47 48
@@ -57,12 +58,11 @@ static int max77693_chg_get_current_limit(struct regulator_dev *rdev)
57{ 58{
58 unsigned int chg_min_uA = rdev->constraints->min_uA; 59 unsigned int chg_min_uA = rdev->constraints->min_uA;
59 unsigned int chg_max_uA = rdev->constraints->max_uA; 60 unsigned int chg_max_uA = rdev->constraints->max_uA;
60 u8 reg, sel; 61 unsigned int reg, sel;
61 unsigned int val; 62 unsigned int val;
62 int ret; 63 int ret;
63 64
64 ret = max77693_read_reg(rdev->regmap, 65 ret = regmap_read(rdev->regmap, MAX77693_CHG_REG_CHG_CNFG_09, &reg);
65 MAX77693_CHG_REG_CHG_CNFG_09, &reg);
66 if (ret < 0) 66 if (ret < 0)
67 return ret; 67 return ret;
68 68
@@ -96,7 +96,7 @@ static int max77693_chg_set_current_limit(struct regulator_dev *rdev,
96 /* the first four codes for charger current are all 60mA */ 96 /* the first four codes for charger current are all 60mA */
97 sel += 3; 97 sel += 3;
98 98
99 return max77693_write_reg(rdev->regmap, 99 return regmap_write(rdev->regmap,
100 MAX77693_CHG_REG_CHG_CNFG_09, sel); 100 MAX77693_CHG_REG_CHG_CNFG_09, sel);
101} 101}
102/* end of CHARGER regulator ops */ 102/* end of CHARGER regulator ops */
diff --git a/include/linux/extcon/sm5502.h b/include/linux/extcon/sm5502.h
new file mode 100644
index 000000000000..030526bf8d79
--- /dev/null
+++ b/include/linux/extcon/sm5502.h
@@ -0,0 +1,287 @@
1/*
2 * sm5502.h
3 *
4 * Copyright (c) 2014 Samsung Electronics Co., Ltd
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#ifndef __LINUX_EXTCON_SM5502_H
18#define __LINUX_EXTCON_SM5502_H
19
20enum sm5502_types {
21 TYPE_SM5502,
22};
23
24/* SM5502 registers */
25enum sm5502_reg {
26 SM5502_REG_DEVICE_ID = 0x01,
27 SM5502_REG_CONTROL,
28 SM5502_REG_INT1,
29 SM5502_REG_INT2,
30 SM5502_REG_INTMASK1,
31 SM5502_REG_INTMASK2,
32 SM5502_REG_ADC,
33 SM5502_REG_TIMING_SET1,
34 SM5502_REG_TIMING_SET2,
35 SM5502_REG_DEV_TYPE1,
36 SM5502_REG_DEV_TYPE2,
37 SM5502_REG_BUTTON1,
38 SM5502_REG_BUTTON2,
39 SM5502_REG_CAR_KIT_STATUS,
40 SM5502_REG_RSVD1,
41 SM5502_REG_RSVD2,
42 SM5502_REG_RSVD3,
43 SM5502_REG_RSVD4,
44 SM5502_REG_MANUAL_SW1,
45 SM5502_REG_MANUAL_SW2,
46 SM5502_REG_DEV_TYPE3,
47 SM5502_REG_RSVD5,
48 SM5502_REG_RSVD6,
49 SM5502_REG_RSVD7,
50 SM5502_REG_RSVD8,
51 SM5502_REG_RSVD9,
52 SM5502_REG_RESET,
53 SM5502_REG_RSVD10,
54 SM5502_REG_RESERVED_ID1,
55 SM5502_REG_RSVD11,
56 SM5502_REG_RSVD12,
57 SM5502_REG_RESERVED_ID2,
58 SM5502_REG_RSVD13,
59 SM5502_REG_OCP,
60 SM5502_REG_RSVD14,
61 SM5502_REG_RSVD15,
62 SM5502_REG_RSVD16,
63 SM5502_REG_RSVD17,
64 SM5502_REG_RSVD18,
65 SM5502_REG_RSVD19,
66 SM5502_REG_RSVD20,
67 SM5502_REG_RSVD21,
68 SM5502_REG_RSVD22,
69 SM5502_REG_RSVD23,
70 SM5502_REG_RSVD24,
71 SM5502_REG_RSVD25,
72 SM5502_REG_RSVD26,
73 SM5502_REG_RSVD27,
74 SM5502_REG_RSVD28,
75 SM5502_REG_RSVD29,
76 SM5502_REG_RSVD30,
77 SM5502_REG_RSVD31,
78 SM5502_REG_RSVD32,
79 SM5502_REG_RSVD33,
80 SM5502_REG_RSVD34,
81 SM5502_REG_RSVD35,
82 SM5502_REG_RSVD36,
83 SM5502_REG_RESERVED_ID3,
84
85 SM5502_REG_END,
86};
87
88/* Define SM5502 MASK/SHIFT constant */
89#define SM5502_REG_DEVICE_ID_VENDOR_SHIFT 0
90#define SM5502_REG_DEVICE_ID_VERSION_SHIFT 3
91#define SM5502_REG_DEVICE_ID_VENDOR_MASK (0x3 << SM5502_REG_DEVICE_ID_VENDOR_SHIFT)
92#define SM5502_REG_DEVICE_ID_VERSION_MASK (0x1f << SM5502_REG_DEVICE_ID_VERSION_SHIFT)
93
94#define SM5502_REG_CONTROL_MASK_INT_SHIFT 0
95#define SM5502_REG_CONTROL_WAIT_SHIFT 1
96#define SM5502_REG_CONTROL_MANUAL_SW_SHIFT 2
97#define SM5502_REG_CONTROL_RAW_DATA_SHIFT 3
98#define SM5502_REG_CONTROL_SW_OPEN_SHIFT 4
99#define SM5502_REG_CONTROL_MASK_INT_MASK (0x1 << SM5502_REG_CONTROL_MASK_INT_SHIFT)
100#define SM5502_REG_CONTROL_WAIT_MASK (0x1 << SM5502_REG_CONTROL_WAIT_SHIFT)
101#define SM5502_REG_CONTROL_MANUAL_SW_MASK (0x1 << SM5502_REG_CONTROL_MANUAL_SW_SHIFT)
102#define SM5502_REG_CONTROL_RAW_DATA_MASK (0x1 << SM5502_REG_CONTROL_RAW_DATA_SHIFT)
103#define SM5502_REG_CONTROL_SW_OPEN_MASK (0x1 << SM5502_REG_CONTROL_SW_OPEN_SHIFT)
104
105#define SM5502_REG_INTM1_ATTACH_SHIFT 0
106#define SM5502_REG_INTM1_DETACH_SHIFT 1
107#define SM5502_REG_INTM1_KP_SHIFT 2
108#define SM5502_REG_INTM1_LKP_SHIFT 3
109#define SM5502_REG_INTM1_LKR_SHIFT 4
110#define SM5502_REG_INTM1_OVP_EVENT_SHIFT 5
111#define SM5502_REG_INTM1_OCP_EVENT_SHIFT 6
112#define SM5502_REG_INTM1_OVP_OCP_DIS_SHIFT 7
113#define SM5502_REG_INTM1_ATTACH_MASK (0x1 << SM5502_REG_INTM1_ATTACH_SHIFT)
114#define SM5502_REG_INTM1_DETACH_MASK (0x1 << SM5502_REG_INTM1_DETACH_SHIFT)
115#define SM5502_REG_INTM1_KP_MASK (0x1 << SM5502_REG_INTM1_KP_SHIFT)
116#define SM5502_REG_INTM1_LKP_MASK (0x1 << SM5502_REG_INTM1_LKP_SHIFT)
117#define SM5502_REG_INTM1_LKR_MASK (0x1 << SM5502_REG_INTM1_LKR_SHIFT)
118#define SM5502_REG_INTM1_OVP_EVENT_MASK (0x1 << SM5502_REG_INTM1_OVP_EVENT_SHIFT)
119#define SM5502_REG_INTM1_OCP_EVENT_MASK (0x1 << SM5502_REG_INTM1_OCP_EVENT_SHIFT)
120#define SM5502_REG_INTM1_OVP_OCP_DIS_MASK (0x1 << SM5502_REG_INTM1_OVP_OCP_DIS_SHIFT)
121
122#define SM5502_REG_INTM2_VBUS_DET_SHIFT 0
123#define SM5502_REG_INTM2_REV_ACCE_SHIFT 1
124#define SM5502_REG_INTM2_ADC_CHG_SHIFT 2
125#define SM5502_REG_INTM2_STUCK_KEY_SHIFT 3
126#define SM5502_REG_INTM2_STUCK_KEY_RCV_SHIFT 4
127#define SM5502_REG_INTM2_MHL_SHIFT 5
128#define SM5502_REG_INTM2_VBUS_DET_MASK (0x1 << SM5502_REG_INTM2_VBUS_DET_SHIFT)
129#define SM5502_REG_INTM2_REV_ACCE_MASK (0x1 << SM5502_REG_INTM2_REV_ACCE_SHIFT)
130#define SM5502_REG_INTM2_ADC_CHG_MASK (0x1 << SM5502_REG_INTM2_ADC_CHG_SHIFT)
131#define SM5502_REG_INTM2_STUCK_KEY_MASK (0x1 << SM5502_REG_INTM2_STUCK_KEY_SHIFT)
132#define SM5502_REG_INTM2_STUCK_KEY_RCV_MASK (0x1 << SM5502_REG_INTM2_STUCK_KEY_RCV_SHIFT)
133#define SM5502_REG_INTM2_MHL_MASK (0x1 << SM5502_REG_INTM2_MHL_SHIFT)
134
135#define SM5502_REG_ADC_SHIFT 0
136#define SM5502_REG_ADC_MASK (0x1f << SM5502_REG_ADC_SHIFT)
137
138#define SM5502_REG_TIMING_SET1_KEY_PRESS_SHIFT 4
139#define SM5502_REG_TIMING_SET1_KEY_PRESS_MASK (0xf << SM5502_REG_TIMING_SET1_KEY_PRESS_SHIFT)
140#define TIMING_KEY_PRESS_100MS 0x0
141#define TIMING_KEY_PRESS_200MS 0x1
142#define TIMING_KEY_PRESS_300MS 0x2
143#define TIMING_KEY_PRESS_400MS 0x3
144#define TIMING_KEY_PRESS_500MS 0x4
145#define TIMING_KEY_PRESS_600MS 0x5
146#define TIMING_KEY_PRESS_700MS 0x6
147#define TIMING_KEY_PRESS_800MS 0x7
148#define TIMING_KEY_PRESS_900MS 0x8
149#define TIMING_KEY_PRESS_1000MS 0x9
150#define SM5502_REG_TIMING_SET1_ADC_DET_SHIFT 0
151#define SM5502_REG_TIMING_SET1_ADC_DET_MASK (0xf << SM5502_REG_TIMING_SET1_ADC_DET_SHIFT)
152#define TIMING_ADC_DET_50MS 0x0
153#define TIMING_ADC_DET_100MS 0x1
154#define TIMING_ADC_DET_150MS 0x2
155#define TIMING_ADC_DET_200MS 0x3
156#define TIMING_ADC_DET_300MS 0x4
157#define TIMING_ADC_DET_400MS 0x5
158#define TIMING_ADC_DET_500MS 0x6
159#define TIMING_ADC_DET_600MS 0x7
160#define TIMING_ADC_DET_700MS 0x8
161#define TIMING_ADC_DET_800MS 0x9
162#define TIMING_ADC_DET_900MS 0xA
163#define TIMING_ADC_DET_1000MS 0xB
164
165#define SM5502_REG_TIMING_SET2_SW_WAIT_SHIFT 4
166#define SM5502_REG_TIMING_SET2_SW_WAIT_MASK (0xf << SM5502_REG_TIMING_SET2_SW_WAIT_SHIFT)
167#define TIMING_SW_WAIT_10MS 0x0
168#define TIMING_SW_WAIT_30MS 0x1
169#define TIMING_SW_WAIT_50MS 0x2
170#define TIMING_SW_WAIT_70MS 0x3
171#define TIMING_SW_WAIT_90MS 0x4
172#define TIMING_SW_WAIT_110MS 0x5
173#define TIMING_SW_WAIT_130MS 0x6
174#define TIMING_SW_WAIT_150MS 0x7
175#define TIMING_SW_WAIT_170MS 0x8
176#define TIMING_SW_WAIT_190MS 0x9
177#define TIMING_SW_WAIT_210MS 0xA
178#define SM5502_REG_TIMING_SET2_LONG_KEY_SHIFT 0
179#define SM5502_REG_TIMING_SET2_LONG_KEY_MASK (0xf << SM5502_REG_TIMING_SET2_LONG_KEY_SHIFT)
180#define TIMING_LONG_KEY_300MS 0x0
181#define TIMING_LONG_KEY_400MS 0x1
182#define TIMING_LONG_KEY_500MS 0x2
183#define TIMING_LONG_KEY_600MS 0x3
184#define TIMING_LONG_KEY_700MS 0x4
185#define TIMING_LONG_KEY_800MS 0x5
186#define TIMING_LONG_KEY_900MS 0x6
187#define TIMING_LONG_KEY_1000MS 0x7
188#define TIMING_LONG_KEY_1100MS 0x8
189#define TIMING_LONG_KEY_1200MS 0x9
190#define TIMING_LONG_KEY_1300MS 0xA
191#define TIMING_LONG_KEY_1400MS 0xB
192#define TIMING_LONG_KEY_1500MS 0xC
193
194#define SM5502_REG_DEV_TYPE1_AUDIO_TYPE1_SHIFT 0
195#define SM5502_REG_DEV_TYPE1_AUDIO_TYPE2_SHIFT 1
196#define SM5502_REG_DEV_TYPE1_USB_SDP_SHIFT 2
197#define SM5502_REG_DEV_TYPE1_UART_SHIFT 3
198#define SM5502_REG_DEV_TYPE1_CAR_KIT_CHARGER_SHIFT 4
199#define SM5502_REG_DEV_TYPE1_USB_CHG_SHIFT 5
200#define SM5502_REG_DEV_TYPE1_DEDICATED_CHG_SHIFT 6
201#define SM5502_REG_DEV_TYPE1_USB_OTG_SHIFT 7
202#define SM5502_REG_DEV_TYPE1_AUDIO_TYPE1_MASK (0x1 << SM5502_REG_DEV_TYPE1_AUDIO_TYPE1_SHIFT)
203#define SM5502_REG_DEV_TYPE1_AUDIO_TYPE1__MASK (0x1 << SM5502_REG_DEV_TYPE1_AUDIO_TYPE2_SHIFT)
204#define SM5502_REG_DEV_TYPE1_USB_SDP_MASK (0x1 << SM5502_REG_DEV_TYPE1_USB_SDP_SHIFT)
205#define SM5502_REG_DEV_TYPE1_UART_MASK (0x1 << SM5502_REG_DEV_TYPE1_UART_SHIFT)
206#define SM5502_REG_DEV_TYPE1_CAR_KIT_CHARGER_MASK (0x1 << SM5502_REG_DEV_TYPE1_CAR_KIT_CHARGER_SHIFT)
207#define SM5502_REG_DEV_TYPE1_USB_CHG_MASK (0x1 << SM5502_REG_DEV_TYPE1_USB_CHG_SHIFT)
208#define SM5502_REG_DEV_TYPE1_DEDICATED_CHG_MASK (0x1 << SM5502_REG_DEV_TYPE1_DEDICATED_CHG_SHIFT)
209#define SM5502_REG_DEV_TYPE1_USB_OTG_MASK (0x1 << SM5502_REG_DEV_TYPE1_USB_OTG_SHIFT)
210
211#define SM5502_REG_DEV_TYPE2_JIG_USB_ON_SHIFT 0
212#define SM5502_REG_DEV_TYPE2_JIG_USB_OFF_SHIFT 1
213#define SM5502_REG_DEV_TYPE2_JIG_UART_ON_SHIFT 2
214#define SM5502_REG_DEV_TYPE2_JIG_UART_OFF_SHIFT 3
215#define SM5502_REG_DEV_TYPE2_PPD_SHIFT 4
216#define SM5502_REG_DEV_TYPE2_TTY_SHIFT 5
217#define SM5502_REG_DEV_TYPE2_AV_CABLE_SHIFT 6
218#define SM5502_REG_DEV_TYPE2_JIG_USB_ON_MASK (0x1 << SM5502_REG_DEV_TYPE2_JIG_USB_ON_SHIFT)
219#define SM5502_REG_DEV_TYPE2_JIG_USB_OFF_MASK (0x1 << SM5502_REG_DEV_TYPE2_JIG_USB_OFF_SHIFT)
220#define SM5502_REG_DEV_TYPE2_JIG_UART_ON_MASK (0x1 << SM5502_REG_DEV_TYPE2_JIG_UART_ON_SHIFT)
221#define SM5502_REG_DEV_TYPE2_JIG_UART_OFF_MASK (0x1 << SM5502_REG_DEV_TYPE2_JIG_UART_OFF_SHIFT)
222#define SM5502_REG_DEV_TYPE2_PPD_MASK (0x1 << SM5502_REG_DEV_TYPE2_PPD_SHIFT)
223#define SM5502_REG_DEV_TYPE2_TTY_MASK (0x1 << SM5502_REG_DEV_TYPE2_TTY_SHIFT)
224#define SM5502_REG_DEV_TYPE2_AV_CABLE_MASK (0x1 << SM5502_REG_DEV_TYPE2_AV_CABLE_SHIFT)
225
226#define SM5502_REG_MANUAL_SW1_VBUSIN_SHIFT 0
227#define SM5502_REG_MANUAL_SW1_DP_SHIFT 2
228#define SM5502_REG_MANUAL_SW1_DM_SHIFT 5
229#define SM5502_REG_MANUAL_SW1_VBUSIN_MASK (0x3 << SM5502_REG_MANUAL_SW1_VBUSIN_SHIFT)
230#define SM5502_REG_MANUAL_SW1_DP_MASK (0x7 << SM5502_REG_MANUAL_SW1_DP_SHIFT)
231#define SM5502_REG_MANUAL_SW1_DM_MASK (0x7 << SM5502_REG_MANUAL_SW1_DM_SHIFT)
232#define VBUSIN_SWITCH_OPEN 0x0
233#define VBUSIN_SWITCH_VBUSOUT 0x1
234#define VBUSIN_SWITCH_MIC 0x2
235#define VBUSIN_SWITCH_VBUSOUT_WITH_USB 0x3
236#define DM_DP_CON_SWITCH_OPEN 0x0
237#define DM_DP_CON_SWITCH_USB 0x1
238#define DM_DP_CON_SWITCH_AUDIO 0x2
239#define DM_DP_CON_SWITCH_UART 0x3
240#define DM_DP_SWITCH_OPEN ((DM_DP_CON_SWITCH_OPEN <<SM5502_REG_MANUAL_SW1_DP_SHIFT) \
241 | (DM_DP_CON_SWITCH_OPEN <<SM5502_REG_MANUAL_SW1_DM_SHIFT))
242#define DM_DP_SWITCH_USB ((DM_DP_CON_SWITCH_USB <<SM5502_REG_MANUAL_SW1_DP_SHIFT) \
243 | (DM_DP_CON_SWITCH_USB <<SM5502_REG_MANUAL_SW1_DM_SHIFT))
244#define DM_DP_SWITCH_AUDIO ((DM_DP_CON_SWITCH_AUDIO <<SM5502_REG_MANUAL_SW1_DP_SHIFT) \
245 | (DM_DP_CON_SWITCH_AUDIO <<SM5502_REG_MANUAL_SW1_DM_SHIFT))
246#define DM_DP_SWITCH_UART ((DM_DP_CON_SWITCH_UART <<SM5502_REG_MANUAL_SW1_DP_SHIFT) \
247 | (DM_DP_CON_SWITCH_UART <<SM5502_REG_MANUAL_SW1_DM_SHIFT))
248
249/* SM5502 Interrupts */
250enum sm5502_irq {
251 /* INT1 */
252 SM5502_IRQ_INT1_ATTACH,
253 SM5502_IRQ_INT1_DETACH,
254 SM5502_IRQ_INT1_KP,
255 SM5502_IRQ_INT1_LKP,
256 SM5502_IRQ_INT1_LKR,
257 SM5502_IRQ_INT1_OVP_EVENT,
258 SM5502_IRQ_INT1_OCP_EVENT,
259 SM5502_IRQ_INT1_OVP_OCP_DIS,
260
261 /* INT2 */
262 SM5502_IRQ_INT2_VBUS_DET,
263 SM5502_IRQ_INT2_REV_ACCE,
264 SM5502_IRQ_INT2_ADC_CHG,
265 SM5502_IRQ_INT2_STUCK_KEY,
266 SM5502_IRQ_INT2_STUCK_KEY_RCV,
267 SM5502_IRQ_INT2_MHL,
268
269 SM5502_IRQ_NUM,
270};
271
272#define SM5502_IRQ_INT1_ATTACH_MASK BIT(0)
273#define SM5502_IRQ_INT1_DETACH_MASK BIT(1)
274#define SM5502_IRQ_INT1_KP_MASK BIT(2)
275#define SM5502_IRQ_INT1_LKP_MASK BIT(3)
276#define SM5502_IRQ_INT1_LKR_MASK BIT(4)
277#define SM5502_IRQ_INT1_OVP_EVENT_MASK BIT(5)
278#define SM5502_IRQ_INT1_OCP_EVENT_MASK BIT(6)
279#define SM5502_IRQ_INT1_OVP_OCP_DIS_MASK BIT(7)
280#define SM5502_IRQ_INT2_VBUS_DET_MASK BIT(0)
281#define SM5502_IRQ_INT2_REV_ACCE_MASK BIT(1)
282#define SM5502_IRQ_INT2_ADC_CHG_MASK BIT(2)
283#define SM5502_IRQ_INT2_STUCK_KEY_MASK BIT(3)
284#define SM5502_IRQ_INT2_STUCK_KEY_RCV_MASK BIT(4)
285#define SM5502_IRQ_INT2_MHL_MASK BIT(5)
286
287#endif /* __LINUX_EXTCON_SM5502_H */
diff --git a/include/linux/mfd/arizona/pdata.h b/include/linux/mfd/arizona/pdata.h
index 12a5c135c746..4578c72c9b86 100644
--- a/include/linux/mfd/arizona/pdata.h
+++ b/include/linux/mfd/arizona/pdata.h
@@ -127,6 +127,9 @@ struct arizona_pdata {
127 /** Internal pull on GPIO5 is disabled when used for jack detection */ 127 /** Internal pull on GPIO5 is disabled when used for jack detection */
128 bool jd_gpio5_nopull; 128 bool jd_gpio5_nopull;
129 129
130 /** set to true if jackdet contact opens on insert */
131 bool jd_invert;
132
130 /** Use the headphone detect circuit to identify the accessory */ 133 /** Use the headphone detect circuit to identify the accessory */
131 bool hpdet_acc_id; 134 bool hpdet_acc_id;
132 135
diff --git a/include/linux/mfd/max77693-private.h b/include/linux/mfd/max77693-private.h
index 3e050b933dd0..c466ff3e16b8 100644
--- a/include/linux/mfd/max77693-private.h
+++ b/include/linux/mfd/max77693-private.h
@@ -262,6 +262,41 @@ enum max77693_irq_source {
262 MAX77693_IRQ_GROUP_NR, 262 MAX77693_IRQ_GROUP_NR,
263}; 263};
264 264
265#define LED_IRQ_FLED2_OPEN BIT(0)
266#define LED_IRQ_FLED2_SHORT BIT(1)
267#define LED_IRQ_FLED1_OPEN BIT(2)
268#define LED_IRQ_FLED1_SHORT BIT(3)
269#define LED_IRQ_MAX_FLASH BIT(4)
270
271#define TOPSYS_IRQ_T120C_INT BIT(0)
272#define TOPSYS_IRQ_T140C_INT BIT(1)
273#define TOPSYS_IRQ_LOWSYS_INT BIT(3)
274
275#define CHG_IRQ_BYP_I BIT(0)
276#define CHG_IRQ_THM_I BIT(2)
277#define CHG_IRQ_BAT_I BIT(3)
278#define CHG_IRQ_CHG_I BIT(4)
279#define CHG_IRQ_CHGIN_I BIT(6)
280
281#define MUIC_IRQ_INT1_ADC BIT(0)
282#define MUIC_IRQ_INT1_ADC_LOW BIT(1)
283#define MUIC_IRQ_INT1_ADC_ERR BIT(2)
284#define MUIC_IRQ_INT1_ADC1K BIT(3)
285
286#define MUIC_IRQ_INT2_CHGTYP BIT(0)
287#define MUIC_IRQ_INT2_CHGDETREUN BIT(1)
288#define MUIC_IRQ_INT2_DCDTMR BIT(2)
289#define MUIC_IRQ_INT2_DXOVP BIT(3)
290#define MUIC_IRQ_INT2_VBVOLT BIT(4)
291#define MUIC_IRQ_INT2_VIDRM BIT(5)
292
293#define MUIC_IRQ_INT3_EOC BIT(0)
294#define MUIC_IRQ_INT3_CGMBC BIT(1)
295#define MUIC_IRQ_INT3_OVP BIT(2)
296#define MUIC_IRQ_INT3_MBCCHG_ERR BIT(3)
297#define MUIC_IRQ_INT3_CHG_ENABLED BIT(4)
298#define MUIC_IRQ_INT3_BAT_DET BIT(5)
299
265enum max77693_irq { 300enum max77693_irq {
266 /* PMIC - FLASH */ 301 /* PMIC - FLASH */
267 MAX77693_LED_IRQ_FLED2_OPEN, 302 MAX77693_LED_IRQ_FLED2_OPEN,
@@ -282,6 +317,10 @@ enum max77693_irq {
282 MAX77693_CHG_IRQ_CHG_I, 317 MAX77693_CHG_IRQ_CHG_I,
283 MAX77693_CHG_IRQ_CHGIN_I, 318 MAX77693_CHG_IRQ_CHGIN_I,
284 319
320 MAX77693_IRQ_NR,
321};
322
323enum max77693_irq_muic {
285 /* MUIC INT1 */ 324 /* MUIC INT1 */
286 MAX77693_MUIC_IRQ_INT1_ADC, 325 MAX77693_MUIC_IRQ_INT1_ADC,
287 MAX77693_MUIC_IRQ_INT1_ADC_LOW, 326 MAX77693_MUIC_IRQ_INT1_ADC_LOW,
@@ -304,7 +343,7 @@ enum max77693_irq {
304 MAX77693_MUIC_IRQ_INT3_CHG_ENABLED, 343 MAX77693_MUIC_IRQ_INT3_CHG_ENABLED,
305 MAX77693_MUIC_IRQ_INT3_BAT_DET, 344 MAX77693_MUIC_IRQ_INT3_BAT_DET,
306 345
307 MAX77693_IRQ_NR, 346 MAX77693_MUIC_IRQ_NR,
308}; 347};
309 348
310struct max77693_dev { 349struct max77693_dev {
@@ -319,7 +358,10 @@ struct max77693_dev {
319 struct regmap *regmap_muic; 358 struct regmap *regmap_muic;
320 struct regmap *regmap_haptic; 359 struct regmap *regmap_haptic;
321 360
322 struct irq_domain *irq_domain; 361 struct regmap_irq_chip_data *irq_data_led;
362 struct regmap_irq_chip_data *irq_data_topsys;
363 struct regmap_irq_chip_data *irq_data_charger;
364 struct regmap_irq_chip_data *irq_data_muic;
323 365
324 int irq; 366 int irq;
325 int irq_gpio; 367 int irq_gpio;
@@ -332,14 +374,6 @@ enum max77693_types {
332 TYPE_MAX77693, 374 TYPE_MAX77693,
333}; 375};
334 376
335extern int max77693_read_reg(struct regmap *map, u8 reg, u8 *dest);
336extern int max77693_bulk_read(struct regmap *map, u8 reg, int count,
337 u8 *buf);
338extern int max77693_write_reg(struct regmap *map, u8 reg, u8 value);
339extern int max77693_bulk_write(struct regmap *map, u8 reg, int count,
340 u8 *buf);
341extern int max77693_update_reg(struct regmap *map, u8 reg, u8 val, u8 mask);
342
343extern int max77693_irq_init(struct max77693_dev *max77686); 377extern int max77693_irq_init(struct max77693_dev *max77686);
344extern void max77693_irq_exit(struct max77693_dev *max77686); 378extern void max77693_irq_exit(struct max77693_dev *max77686);
345extern int max77693_irq_resume(struct max77693_dev *max77686); 379extern int max77693_irq_resume(struct max77693_dev *max77686);