aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/extcon
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/extcon')
-rw-r--r--drivers/extcon/Kconfig8
-rw-r--r--drivers/extcon/Makefile5
-rw-r--r--drivers/extcon/extcon-adc-jack.c198
-rw-r--r--drivers/extcon/extcon-arizona.c78
-rw-r--r--drivers/extcon/extcon-class.c (renamed from drivers/extcon/extcon_class.c)12
-rw-r--r--drivers/extcon/extcon-gpio.c (renamed from drivers/extcon/extcon_gpio.c)0
-rw-r--r--drivers/extcon/extcon-max77693.c8
7 files changed, 289 insertions, 20 deletions
diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig
index e175c8ed4ec..07122a9ef36 100644
--- a/drivers/extcon/Kconfig
+++ b/drivers/extcon/Kconfig
@@ -21,6 +21,12 @@ config EXTCON_GPIO
21 Say Y here to enable GPIO based extcon support. Note that GPIO 21 Say Y here to enable GPIO based extcon support. Note that GPIO
22 extcon supports single state per extcon instance. 22 extcon supports single state per extcon instance.
23 23
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
24config EXTCON_MAX77693 30config EXTCON_MAX77693
25 tristate "MAX77693 EXTCON Support" 31 tristate "MAX77693 EXTCON Support"
26 depends on MFD_MAX77693 32 depends on MFD_MAX77693
@@ -41,7 +47,7 @@ config EXTCON_MAX8997
41 47
42config EXTCON_ARIZONA 48config EXTCON_ARIZONA
43 tristate "Wolfson Arizona EXTCON support" 49 tristate "Wolfson Arizona EXTCON support"
44 depends on MFD_ARIZONA 50 depends on MFD_ARIZONA && INPUT
45 help 51 help
46 Say Y here to enable support for external accessory detection 52 Say Y here to enable support for external accessory detection
47 with Wolfson Arizona devices. These are audio CODECs with 53 with Wolfson Arizona devices. These are audio CODECs with
diff --git a/drivers/extcon/Makefile b/drivers/extcon/Makefile
index 88961b33234..f98a3c4d46e 100644
--- a/drivers/extcon/Makefile
+++ b/drivers/extcon/Makefile
@@ -2,8 +2,9 @@
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 6obj-$(CONFIG_EXTCON_GPIO) += extcon-gpio.o
7obj-$(CONFIG_EXTCON_ADC_JACK) += extcon-adc-jack.o
7obj-$(CONFIG_EXTCON_MAX77693) += extcon-max77693.o 8obj-$(CONFIG_EXTCON_MAX77693) += extcon-max77693.o
8obj-$(CONFIG_EXTCON_MAX8997) += extcon-max8997.o 9obj-$(CONFIG_EXTCON_MAX8997) += extcon-max8997.o
9obj-$(CONFIG_EXTCON_ARIZONA) += extcon-arizona.o 10obj-$(CONFIG_EXTCON_ARIZONA) += extcon-arizona.o
diff --git a/drivers/extcon/extcon-adc-jack.c b/drivers/extcon/extcon-adc-jack.c
new file mode 100644
index 00000000000..60ac3fbb4cd
--- /dev/null
+++ b/drivers/extcon/extcon-adc-jack.c
@@ -0,0 +1,198 @@
1/*
2 * drivers/extcon/extcon-adc-jack.c
3 *
4 * Analog Jack extcon driver with ADC-based detection capability.
5 *
6 * Copyright (C) 2012 Samsung Electronics
7 * MyungJoo Ham <myungjoo.ham@samsung.com>
8 *
9 * Modified for calling to IIO to get adc by <anish.singh@samsung.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 */
16
17#include <linux/slab.h>
18#include <linux/device.h>
19#include <linux/platform_device.h>
20#include <linux/err.h>
21#include <linux/interrupt.h>
22#include <linux/workqueue.h>
23#include <linux/iio/consumer.h>
24#include <linux/extcon/extcon-adc-jack.h>
25#include <linux/extcon.h>
26
27/**
28 * struct adc_jack_data - internal data for adc_jack device driver
29 * @edev - extcon device.
30 * @cable_names - list of supported cables.
31 * @num_cables - size of cable_names.
32 * @adc_conditions - list of adc value conditions.
33 * @num_conditions - size of adc_conditions.
34 * @irq - irq number of attach/detach event (0 if not exist).
35 * @handling_delay - interrupt handler will schedule extcon event
36 * handling at handling_delay jiffies.
37 * @handler - extcon event handler called by interrupt handler.
38 * @chan - iio channel being queried.
39 */
40struct adc_jack_data {
41 struct extcon_dev edev;
42
43 const char **cable_names;
44 int num_cables;
45 struct adc_jack_cond *adc_conditions;
46 int num_conditions;
47
48 int irq;
49 unsigned long handling_delay; /* in jiffies */
50 struct delayed_work handler;
51
52 struct iio_channel *chan;
53};
54
55static void adc_jack_handler(struct work_struct *work)
56{
57 struct adc_jack_data *data = container_of(to_delayed_work(work),
58 struct adc_jack_data,
59 handler);
60 u32 state = 0;
61 int ret, adc_val;
62 int i;
63
64 ret = iio_read_channel_raw(data->chan, &adc_val);
65 if (ret < 0) {
66 dev_err(data->edev.dev, "read channel() error: %d\n", ret);
67 return;
68 }
69
70 /* Get state from adc value with adc_conditions */
71 for (i = 0; i < data->num_conditions; i++) {
72 struct adc_jack_cond *def = &data->adc_conditions[i];
73 if (!def->state)
74 break;
75 if (def->min_adc <= adc_val && def->max_adc >= adc_val) {
76 state = def->state;
77 break;
78 }
79 }
80 /* if no def has met, it means state = 0 (no cables attached) */
81
82 extcon_set_state(&data->edev, state);
83}
84
85static irqreturn_t adc_jack_irq_thread(int irq, void *_data)
86{
87 struct adc_jack_data *data = _data;
88
89 schedule_delayed_work(&data->handler, data->handling_delay);
90 return IRQ_HANDLED;
91}
92
93static int __devinit adc_jack_probe(struct platform_device *pdev)
94{
95 struct adc_jack_data *data;
96 struct adc_jack_pdata *pdata = pdev->dev.platform_data;
97 int i, err = 0;
98
99 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
100 if (!data)
101 return -ENOMEM;
102
103 data->edev.name = pdata->name;
104
105 if (!pdata->cable_names) {
106 err = -EINVAL;
107 dev_err(&pdev->dev, "error: cable_names not defined.\n");
108 goto out;
109 }
110
111 data->edev.supported_cable = pdata->cable_names;
112
113 /* Check the length of array and set num_cables */
114 for (i = 0; data->edev.supported_cable[i]; i++)
115 ;
116 if (i == 0 || i > SUPPORTED_CABLE_MAX) {
117 err = -EINVAL;
118 dev_err(&pdev->dev, "error: pdata->cable_names size = %d\n",
119 i - 1);
120 goto out;
121 }
122 data->num_cables = i;
123
124 if (!pdata->adc_conditions ||
125 !pdata->adc_conditions[0].state) {
126 err = -EINVAL;
127 dev_err(&pdev->dev, "error: adc_conditions not defined.\n");
128 goto out;
129 }
130 data->adc_conditions = pdata->adc_conditions;
131
132 /* Check the length of array and set num_conditions */
133 for (i = 0; data->adc_conditions[i].state; i++)
134 ;
135 data->num_conditions = i;
136
137 data->chan = iio_channel_get(dev_name(&pdev->dev),
138 pdata->consumer_channel);
139 if (IS_ERR(data->chan)) {
140 err = PTR_ERR(data->chan);
141 goto out;
142 }
143
144 data->handling_delay = msecs_to_jiffies(pdata->handling_delay_ms);
145
146 INIT_DELAYED_WORK_DEFERRABLE(&data->handler, adc_jack_handler);
147
148 platform_set_drvdata(pdev, data);
149
150 err = extcon_dev_register(&data->edev, &pdev->dev);
151 if (err)
152 goto out;
153
154 data->irq = platform_get_irq(pdev, 0);
155 if (!data->irq) {
156 dev_err(&pdev->dev, "platform_get_irq failed\n");
157 err = -ENODEV;
158 goto err_irq;
159 }
160
161 err = request_any_context_irq(data->irq, adc_jack_irq_thread,
162 pdata->irq_flags, pdata->name, data);
163
164 if (err) {
165 dev_err(&pdev->dev, "error: irq %d\n", data->irq);
166 err = -EINVAL;
167 goto err_irq;
168 }
169
170 goto out;
171
172err_irq:
173 extcon_dev_unregister(&data->edev);
174out:
175 return err;
176}
177
178static int __devexit adc_jack_remove(struct platform_device *pdev)
179{
180 struct adc_jack_data *data = platform_get_drvdata(pdev);
181
182 free_irq(data->irq, data);
183 cancel_work_sync(&data->handler.work);
184 extcon_dev_unregister(&data->edev);
185
186 return 0;
187}
188
189static struct platform_driver adc_jack_driver = {
190 .probe = adc_jack_probe,
191 .remove = __devexit_p(adc_jack_remove),
192 .driver = {
193 .name = "adc-jack",
194 .owner = THIS_MODULE,
195 },
196};
197
198module_platform_driver(adc_jack_driver);
diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c
index 6c19833ed2d..cdab9e59829 100644
--- a/drivers/extcon/extcon-arizona.c
+++ b/drivers/extcon/extcon-arizona.c
@@ -21,6 +21,7 @@
21#include <linux/interrupt.h> 21#include <linux/interrupt.h>
22#include <linux/err.h> 22#include <linux/err.h>
23#include <linux/gpio.h> 23#include <linux/gpio.h>
24#include <linux/input.h>
24#include <linux/platform_device.h> 25#include <linux/platform_device.h>
25#include <linux/pm_runtime.h> 26#include <linux/pm_runtime.h>
26#include <linux/regulator/consumer.h> 27#include <linux/regulator/consumer.h>
@@ -30,11 +31,14 @@
30#include <linux/mfd/arizona/pdata.h> 31#include <linux/mfd/arizona/pdata.h>
31#include <linux/mfd/arizona/registers.h> 32#include <linux/mfd/arizona/registers.h>
32 33
34#define ARIZONA_NUM_BUTTONS 6
35
33struct arizona_extcon_info { 36struct arizona_extcon_info {
34 struct device *dev; 37 struct device *dev;
35 struct arizona *arizona; 38 struct arizona *arizona;
36 struct mutex lock; 39 struct mutex lock;
37 struct regulator *micvdd; 40 struct regulator *micvdd;
41 struct input_dev *input;
38 42
39 int micd_mode; 43 int micd_mode;
40 const struct arizona_micd_config *micd_modes; 44 const struct arizona_micd_config *micd_modes;
@@ -54,6 +58,18 @@ static const struct arizona_micd_config micd_default_modes[] = {
54 { 0, 2 << ARIZONA_MICD_BIAS_SRC_SHIFT, 1 }, 58 { 0, 2 << ARIZONA_MICD_BIAS_SRC_SHIFT, 1 },
55}; 59};
56 60
61static struct {
62 u16 status;
63 int report;
64} arizona_lvl_to_key[ARIZONA_NUM_BUTTONS] = {
65 { 0x1, BTN_0 },
66 { 0x2, BTN_1 },
67 { 0x4, BTN_2 },
68 { 0x8, BTN_3 },
69 { 0x10, BTN_4 },
70 { 0x20, BTN_5 },
71};
72
57#define ARIZONA_CABLE_MECHANICAL 0 73#define ARIZONA_CABLE_MECHANICAL 0
58#define ARIZONA_CABLE_MICROPHONE 1 74#define ARIZONA_CABLE_MICROPHONE 1
59#define ARIZONA_CABLE_HEADPHONE 2 75#define ARIZONA_CABLE_HEADPHONE 2
@@ -133,6 +149,7 @@ static void arizona_stop_mic(struct arizona_extcon_info *info)
133 149
134 if (change) { 150 if (change) {
135 regulator_disable(info->micvdd); 151 regulator_disable(info->micvdd);
152 pm_runtime_mark_last_busy(info->dev);
136 pm_runtime_put_autosuspend(info->dev); 153 pm_runtime_put_autosuspend(info->dev);
137 } 154 }
138} 155}
@@ -141,8 +158,8 @@ static irqreturn_t arizona_micdet(int irq, void *data)
141{ 158{
142 struct arizona_extcon_info *info = data; 159 struct arizona_extcon_info *info = data;
143 struct arizona *arizona = info->arizona; 160 struct arizona *arizona = info->arizona;
144 unsigned int val; 161 unsigned int val, lvl;
145 int ret; 162 int ret, i;
146 163
147 mutex_lock(&info->lock); 164 mutex_lock(&info->lock);
148 165
@@ -219,13 +236,22 @@ static irqreturn_t arizona_micdet(int irq, void *data)
219 236
220 /* 237 /*
221 * If we're still detecting and we detect a short then we've 238 * If we're still detecting and we detect a short then we've
222 * got a headphone. Otherwise it's a button press, the 239 * got a headphone. Otherwise it's a button press.
223 * button reporting is stubbed out for now.
224 */ 240 */
225 if (val & 0x3fc) { 241 if (val & 0x3fc) {
226 if (info->mic) { 242 if (info->mic) {
227 dev_dbg(arizona->dev, "Mic button detected\n"); 243 dev_dbg(arizona->dev, "Mic button detected\n");
228 244
245 lvl = val & ARIZONA_MICD_LVL_MASK;
246 lvl >>= ARIZONA_MICD_LVL_SHIFT;
247
248 for (i = 0; i < ARIZONA_NUM_BUTTONS; i++)
249 if (lvl & arizona_lvl_to_key[i].status)
250 input_report_key(info->input,
251 arizona_lvl_to_key[i].report,
252 1);
253 input_sync(info->input);
254
229 } else if (info->detecting) { 255 } else if (info->detecting) {
230 dev_dbg(arizona->dev, "Headphone detected\n"); 256 dev_dbg(arizona->dev, "Headphone detected\n");
231 info->detecting = false; 257 info->detecting = false;
@@ -244,6 +270,10 @@ static irqreturn_t arizona_micdet(int irq, void *data)
244 } 270 }
245 } else { 271 } else {
246 dev_dbg(arizona->dev, "Mic button released\n"); 272 dev_dbg(arizona->dev, "Mic button released\n");
273 for (i = 0; i < ARIZONA_NUM_BUTTONS; i++)
274 input_report_key(info->input,
275 arizona_lvl_to_key[i].report, 0);
276 input_sync(info->input);
247 } 277 }
248 278
249handled: 279handled:
@@ -258,7 +288,7 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
258 struct arizona_extcon_info *info = data; 288 struct arizona_extcon_info *info = data;
259 struct arizona *arizona = info->arizona; 289 struct arizona *arizona = info->arizona;
260 unsigned int val; 290 unsigned int val;
261 int ret; 291 int ret, i;
262 292
263 pm_runtime_get_sync(info->dev); 293 pm_runtime_get_sync(info->dev);
264 294
@@ -288,6 +318,11 @@ static irqreturn_t arizona_jackdet(int irq, void *data)
288 318
289 arizona_stop_mic(info); 319 arizona_stop_mic(info);
290 320
321 for (i = 0; i < ARIZONA_NUM_BUTTONS; i++)
322 input_report_key(info->input,
323 arizona_lvl_to_key[i].report, 0);
324 input_sync(info->input);
325
291 ret = extcon_update_state(&info->edev, 0xffffffff, 0); 326 ret = extcon_update_state(&info->edev, 0xffffffff, 0);
292 if (ret != 0) 327 if (ret != 0)
293 dev_err(arizona->dev, "Removal report failed: %d\n", 328 dev_err(arizona->dev, "Removal report failed: %d\n",
@@ -307,13 +342,13 @@ static int __devinit arizona_extcon_probe(struct platform_device *pdev)
307 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent); 342 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
308 struct arizona_pdata *pdata; 343 struct arizona_pdata *pdata;
309 struct arizona_extcon_info *info; 344 struct arizona_extcon_info *info;
310 int ret, mode; 345 int ret, mode, i;
311 346
312 pdata = dev_get_platdata(arizona->dev); 347 pdata = dev_get_platdata(arizona->dev);
313 348
314 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); 349 info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
315 if (!info) { 350 if (!info) {
316 dev_err(&pdev->dev, "failed to allocate memory\n"); 351 dev_err(&pdev->dev, "Failed to allocate memory\n");
317 ret = -ENOMEM; 352 ret = -ENOMEM;
318 goto err; 353 goto err;
319 } 354 }
@@ -350,7 +385,7 @@ static int __devinit arizona_extcon_probe(struct platform_device *pdev)
350 385
351 ret = extcon_dev_register(&info->edev, arizona->dev); 386 ret = extcon_dev_register(&info->edev, arizona->dev);
352 if (ret < 0) { 387 if (ret < 0) {
353 dev_err(arizona->dev, "extcon_dev_regster() failed: %d\n", 388 dev_err(arizona->dev, "extcon_dev_register() failed: %d\n",
354 ret); 389 ret);
355 goto err; 390 goto err;
356 } 391 }
@@ -382,6 +417,20 @@ static int __devinit arizona_extcon_probe(struct platform_device *pdev)
382 417
383 arizona_extcon_set_mode(info, 0); 418 arizona_extcon_set_mode(info, 0);
384 419
420 info->input = input_allocate_device();
421 if (!info->input) {
422 dev_err(arizona->dev, "Can't allocate input dev\n");
423 ret = -ENOMEM;
424 goto err_register;
425 }
426
427 for (i = 0; i < ARIZONA_NUM_BUTTONS; i++)
428 input_set_capability(info->input, EV_KEY,
429 arizona_lvl_to_key[i].report);
430 info->input->name = "Headset";
431 info->input->phys = "arizona/extcon";
432 info->input->dev.parent = &pdev->dev;
433
385 pm_runtime_enable(&pdev->dev); 434 pm_runtime_enable(&pdev->dev);
386 pm_runtime_idle(&pdev->dev); 435 pm_runtime_idle(&pdev->dev);
387 pm_runtime_get_sync(&pdev->dev); 436 pm_runtime_get_sync(&pdev->dev);
@@ -391,7 +440,7 @@ static int __devinit arizona_extcon_probe(struct platform_device *pdev)
391 if (ret != 0) { 440 if (ret != 0) {
392 dev_err(&pdev->dev, "Failed to get JACKDET rise IRQ: %d\n", 441 dev_err(&pdev->dev, "Failed to get JACKDET rise IRQ: %d\n",
393 ret); 442 ret);
394 goto err_register; 443 goto err_input;
395 } 444 }
396 445
397 ret = arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_RISE, 1); 446 ret = arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_RISE, 1);
@@ -441,8 +490,16 @@ static int __devinit arizona_extcon_probe(struct platform_device *pdev)
441 490
442 pm_runtime_put(&pdev->dev); 491 pm_runtime_put(&pdev->dev);
443 492
493 ret = input_register_device(info->input);
494 if (ret) {
495 dev_err(&pdev->dev, "Can't register input device: %d\n", ret);
496 goto err_micdet;
497 }
498
444 return 0; 499 return 0;
445 500
501err_micdet:
502 arizona_free_irq(arizona, ARIZONA_IRQ_MICDET, info);
446err_fall_wake: 503err_fall_wake:
447 arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_FALL, 0); 504 arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_FALL, 0);
448err_fall: 505err_fall:
@@ -451,6 +508,8 @@ err_rise_wake:
451 arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_RISE, 0); 508 arizona_set_irq_wake(arizona, ARIZONA_IRQ_JD_RISE, 0);
452err_rise: 509err_rise:
453 arizona_free_irq(arizona, ARIZONA_IRQ_JD_RISE, info); 510 arizona_free_irq(arizona, ARIZONA_IRQ_JD_RISE, info);
511err_input:
512 input_free_device(info->input);
454err_register: 513err_register:
455 pm_runtime_disable(&pdev->dev); 514 pm_runtime_disable(&pdev->dev);
456 extcon_dev_unregister(&info->edev); 515 extcon_dev_unregister(&info->edev);
@@ -473,6 +532,7 @@ static int __devexit arizona_extcon_remove(struct platform_device *pdev)
473 regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE, 532 regmap_update_bits(arizona->regmap, ARIZONA_JACK_DETECT_ANALOGUE,
474 ARIZONA_JD1_ENA, 0); 533 ARIZONA_JD1_ENA, 0);
475 arizona_clk32k_disable(arizona); 534 arizona_clk32k_disable(arizona);
535 input_unregister_device(info->input);
476 extcon_dev_unregister(&info->edev); 536 extcon_dev_unregister(&info->edev);
477 537
478 return 0; 538 return 0;
diff --git a/drivers/extcon/extcon_class.c b/drivers/extcon/extcon-class.c
index f6419f9db76..946a3188b2b 100644
--- a/drivers/extcon/extcon_class.c
+++ b/drivers/extcon/extcon-class.c
@@ -30,6 +30,7 @@
30#include <linux/err.h> 30#include <linux/err.h>
31#include <linux/extcon.h> 31#include <linux/extcon.h>
32#include <linux/slab.h> 32#include <linux/slab.h>
33#include <linux/sysfs.h>
33 34
34/* 35/*
35 * extcon_cable_name suggests the standard cable names for commonly used 36 * extcon_cable_name suggests the standard cable names for commonly used
@@ -442,7 +443,7 @@ static int _call_per_cable(struct notifier_block *nb, unsigned long val,
442 443
443/** 444/**
444 * extcon_register_interest() - Register a notifier for a state change of a 445 * extcon_register_interest() - Register a notifier for a state change of a
445 * specific cable, not a entier set of cables of a 446 * specific cable, not an entier set of cables of a
446 * extcon device. 447 * extcon device.
447 * @obj: an empty extcon_specific_cable_nb object to be returned. 448 * @obj: an empty extcon_specific_cable_nb object to be returned.
448 * @extcon_name: the name of extcon device. 449 * @extcon_name: the name of extcon device.
@@ -498,7 +499,7 @@ int extcon_unregister_interest(struct extcon_specific_cable_nb *obj)
498} 499}
499 500
500/** 501/**
501 * extcon_register_notifier() - Register a notifee to get notified by 502 * extcon_register_notifier() - Register a notifiee to get notified by
502 * any attach status changes from the extcon. 503 * any attach status changes from the extcon.
503 * @edev: the extcon device. 504 * @edev: the extcon device.
504 * @nb: a notifier block to be registered. 505 * @nb: a notifier block to be registered.
@@ -515,7 +516,7 @@ int extcon_register_notifier(struct extcon_dev *edev,
515EXPORT_SYMBOL_GPL(extcon_register_notifier); 516EXPORT_SYMBOL_GPL(extcon_register_notifier);
516 517
517/** 518/**
518 * extcon_unregister_notifier() - Unregister a notifee from the extcon device. 519 * extcon_unregister_notifier() - Unregister a notifiee from the extcon device.
519 * @edev: the extcon device. 520 * @edev: the extcon device.
520 * @nb: a registered notifier block to be unregistered. 521 * @nb: a registered notifier block to be unregistered.
521 */ 522 */
@@ -673,10 +674,12 @@ int extcon_dev_register(struct extcon_dev *edev, struct device *dev)
673 cable->attr_g.name = str; 674 cable->attr_g.name = str;
674 cable->attr_g.attrs = cable->attrs; 675 cable->attr_g.attrs = cable->attrs;
675 676
677 sysfs_attr_init(&cable->attr_name.attr);
676 cable->attr_name.attr.name = "name"; 678 cable->attr_name.attr.name = "name";
677 cable->attr_name.attr.mode = 0444; 679 cable->attr_name.attr.mode = 0444;
678 cable->attr_name.show = cable_name_show; 680 cable->attr_name.show = cable_name_show;
679 681
682 sysfs_attr_init(&cable->attr_state.attr);
680 cable->attr_state.attr.name = "state"; 683 cable->attr_state.attr.name = "state";
681 cable->attr_state.attr.mode = 0644; 684 cable->attr_state.attr.mode = 0644;
682 cable->attr_state.show = cable_state_show; 685 cable->attr_state.show = cable_state_show;
@@ -722,6 +725,7 @@ int extcon_dev_register(struct extcon_dev *edev, struct device *dev)
722 goto err_muex; 725 goto err_muex;
723 } 726 }
724 strcpy(name, buf); 727 strcpy(name, buf);
728 sysfs_attr_init(&edev->d_attrs_muex[index].attr);
725 edev->d_attrs_muex[index].attr.name = name; 729 edev->d_attrs_muex[index].attr.name = name;
726 edev->d_attrs_muex[index].attr.mode = 0000; 730 edev->d_attrs_muex[index].attr.mode = 0000;
727 edev->attrs_muex[index] = &edev->d_attrs_muex[index] 731 edev->attrs_muex[index] = &edev->d_attrs_muex[index]
@@ -802,7 +806,7 @@ EXPORT_SYMBOL_GPL(extcon_dev_register);
802 806
803/** 807/**
804 * extcon_dev_unregister() - Unregister the extcon device. 808 * extcon_dev_unregister() - Unregister the extcon device.
805 * @edev: the extcon device instance to be unregitered. 809 * @edev: the extcon device instance to be unregistered.
806 * 810 *
807 * Note that this does not call kfree(edev) because edev was not allocated 811 * Note that this does not call kfree(edev) because edev was not allocated
808 * by this class. 812 * by this class.
diff --git a/drivers/extcon/extcon_gpio.c b/drivers/extcon/extcon-gpio.c
index 3cc152e690b..3cc152e690b 100644
--- a/drivers/extcon/extcon_gpio.c
+++ b/drivers/extcon/extcon-gpio.c
diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c
index 38f9e52f358..e21387e2da5 100644
--- a/drivers/extcon/extcon-max77693.c
+++ b/drivers/extcon/extcon-max77693.c
@@ -356,7 +356,7 @@ static int max77693_muic_adc_ground_handler(struct max77693_muic_info *info,
356 extcon_set_cable_state(info->edev, "MHL", attached); 356 extcon_set_cable_state(info->edev, "MHL", attached);
357 break; 357 break;
358 default: 358 default:
359 dev_err(info->dev, "faild to detect %s accessory\n", 359 dev_err(info->dev, "failed to detect %s accessory\n",
360 attached ? "attached" : "detached"); 360 attached ? "attached" : "detached");
361 dev_err(info->dev, "- adc:0x%x, adclow:0x%x, adc1k:0x%x\n", 361 dev_err(info->dev, "- adc:0x%x, adclow:0x%x, adc1k:0x%x\n",
362 adc, adclow, adc1k); 362 adc, adclow, adc1k);
@@ -548,7 +548,7 @@ static void max77693_muic_irq_work(struct work_struct *work)
548 curr_adc = info->status[0] & STATUS1_ADC_MASK; 548 curr_adc = info->status[0] & STATUS1_ADC_MASK;
549 curr_adc >>= STATUS1_ADC_SHIFT; 549 curr_adc >>= STATUS1_ADC_SHIFT;
550 550
551 /* Check accossory state which is either detached or attached */ 551 /* Check accessory state which is either detached or attached */
552 if (curr_adc == MAX77693_MUIC_ADC_OPEN) 552 if (curr_adc == MAX77693_MUIC_ADC_OPEN)
553 attached = false; 553 attached = false;
554 554
@@ -564,7 +564,7 @@ static void max77693_muic_irq_work(struct work_struct *work)
564 curr_chg_type = info->status[1] & STATUS2_CHGTYP_MASK; 564 curr_chg_type = info->status[1] & STATUS2_CHGTYP_MASK;
565 curr_chg_type >>= STATUS2_CHGTYP_SHIFT; 565 curr_chg_type >>= STATUS2_CHGTYP_SHIFT;
566 566
567 /* Check charger accossory state which 567 /* Check charger accessory state which
568 is either detached or attached */ 568 is either detached or attached */
569 if (curr_chg_type == MAX77693_CHARGER_TYPE_NONE) 569 if (curr_chg_type == MAX77693_CHARGER_TYPE_NONE)
570 attached = false; 570 attached = false;
@@ -699,7 +699,7 @@ static int __devinit max77693_muic_probe(struct platform_device *pdev)
699 699
700 ret = request_threaded_irq(virq, NULL, 700 ret = request_threaded_irq(virq, NULL,
701 max77693_muic_irq_handler, 701 max77693_muic_irq_handler,
702 0, muic_irq->name, info); 702 IRQF_ONESHOT, muic_irq->name, info);
703 if (ret) { 703 if (ret) {
704 dev_err(&pdev->dev, 704 dev_err(&pdev->dev,
705 "failed: irq request (IRQ: %d," 705 "failed: irq request (IRQ: %d,"