xref: /openbmc/linux/drivers/extcon/extcon.c (revision 2a9de9c0)
1 /*
2  *  drivers/extcon/extcon.c - External Connector (extcon) framework.
3  *
4  *  External connector (extcon) class driver
5  *
6  * Copyright (C) 2015 Samsung Electronics
7  * Author: Chanwoo Choi <cw00.choi@samsung.com>
8  *
9  * Copyright (C) 2012 Samsung Electronics
10  * Author: Donggeun Kim <dg77.kim@samsung.com>
11  * Author: MyungJoo Ham <myungjoo.ham@samsung.com>
12  *
13  * based on android/drivers/switch/switch_class.c
14  * Copyright (C) 2008 Google, Inc.
15  * Author: Mike Lockwood <lockwood@android.com>
16  *
17  * This software is licensed under the terms of the GNU General Public
18  * License version 2, as published by the Free Software Foundation, and
19  * may be copied, distributed, and modified under those terms.
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  * GNU General Public License for more details.
25  */
26 
27 #include <linux/module.h>
28 #include <linux/types.h>
29 #include <linux/init.h>
30 #include <linux/device.h>
31 #include <linux/fs.h>
32 #include <linux/err.h>
33 #include <linux/extcon.h>
34 #include <linux/of.h>
35 #include <linux/slab.h>
36 #include <linux/sysfs.h>
37 
38 #define SUPPORTED_CABLE_MAX	32
39 #define CABLE_NAME_MAX		30
40 
41 static const char *extcon_name[] =  {
42 	[EXTCON_USB]		= "USB",
43 	[EXTCON_USB_HOST]	= "USB-Host",
44 	[EXTCON_TA]		= "TA",
45 	[EXTCON_FAST_CHARGER]	= "Fast-charger",
46 	[EXTCON_SLOW_CHARGER]	= "Slow-charger",
47 	[EXTCON_CHARGE_DOWNSTREAM]	= "Charge-downstream",
48 	[EXTCON_LINE_IN]	= "Line-in",
49 	[EXTCON_LINE_OUT]	= "Line-out",
50 	[EXTCON_MICROPHONE]	= "Microphone",
51 	[EXTCON_HEADPHONE]	= "Headphone",
52 	[EXTCON_HDMI]		= "HDMI",
53 	[EXTCON_MHL]		= "MHL",
54 	[EXTCON_DVI]		= "DVI",
55 	[EXTCON_VGA]		= "VGA",
56 	[EXTCON_SPDIF_IN]	= "SPDIF-in",
57 	[EXTCON_SPDIF_OUT]	= "SPDIF-out",
58 	[EXTCON_VIDEO_IN]	= "Video-in",
59 	[EXTCON_VIDEO_OUT]	= "Video-out",
60 	[EXTCON_DOCK]		= "Dock",
61 	[EXTCON_JIG]		= "JIG",
62 	[EXTCON_MECHANICAL]	= "Mechanical",
63 	NULL,
64 };
65 
66 static struct class *extcon_class;
67 #if defined(CONFIG_ANDROID)
68 static struct class_compat *switch_class;
69 #endif /* CONFIG_ANDROID */
70 
71 static LIST_HEAD(extcon_dev_list);
72 static DEFINE_MUTEX(extcon_dev_list_lock);
73 
74 /**
75  * check_mutually_exclusive - Check if new_state violates mutually_exclusive
76  *			      condition.
77  * @edev:	the extcon device
78  * @new_state:	new cable attach status for @edev
79  *
80  * Returns 0 if nothing violates. Returns the index + 1 for the first
81  * violated condition.
82  */
83 static int check_mutually_exclusive(struct extcon_dev *edev, u32 new_state)
84 {
85 	int i = 0;
86 
87 	if (!edev->mutually_exclusive)
88 		return 0;
89 
90 	for (i = 0; edev->mutually_exclusive[i]; i++) {
91 		int weight;
92 		u32 correspondants = new_state & edev->mutually_exclusive[i];
93 
94 		/* calculate the total number of bits set */
95 		weight = hweight32(correspondants);
96 		if (weight > 1)
97 			return i + 1;
98 	}
99 
100 	return 0;
101 }
102 
103 static int find_cable_index_by_id(struct extcon_dev *edev, const enum extcon id)
104 {
105 	int i;
106 
107 	/* Find the the index of extcon cable in edev->supported_cable */
108 	for (i = 0; i < edev->max_supported; i++) {
109 		if (edev->supported_cable[i] == id)
110 			return i;
111 	}
112 
113 	return -EINVAL;
114 }
115 
116 static int find_cable_index_by_name(struct extcon_dev *edev, const char *name)
117 {
118 	enum extcon id = EXTCON_NONE;
119 	int i;
120 
121 	if (edev->max_supported == 0)
122 		return -EINVAL;
123 
124 	/* Find the the number of extcon cable */
125 	for (i = 0; i < EXTCON_END; i++) {
126 		if (!extcon_name[i])
127 			continue;
128 		if (!strncmp(extcon_name[i], name, CABLE_NAME_MAX)) {
129 			id = i;
130 			break;
131 		}
132 	}
133 
134 	if (id == EXTCON_NONE)
135 		return -EINVAL;
136 
137 	return find_cable_index_by_id(edev, id);
138 }
139 
140 static ssize_t state_show(struct device *dev, struct device_attribute *attr,
141 			  char *buf)
142 {
143 	int i, count = 0;
144 	struct extcon_dev *edev = dev_get_drvdata(dev);
145 
146 	if (edev->print_state) {
147 		int ret = edev->print_state(edev, buf);
148 
149 		if (ret >= 0)
150 			return ret;
151 		/* Use default if failed */
152 	}
153 
154 	if (edev->max_supported == 0)
155 		return sprintf(buf, "%u\n", edev->state);
156 
157 	for (i = 0; i < edev->max_supported; i++) {
158 		count += sprintf(buf + count, "%s=%d\n",
159 				extcon_name[edev->supported_cable[i]],
160 				 !!(edev->state & (1 << i)));
161 	}
162 
163 	return count;
164 }
165 
166 static ssize_t state_store(struct device *dev, struct device_attribute *attr,
167 			   const char *buf, size_t count)
168 {
169 	u32 state;
170 	ssize_t ret = 0;
171 	struct extcon_dev *edev = dev_get_drvdata(dev);
172 
173 	ret = sscanf(buf, "0x%x", &state);
174 	if (ret == 0)
175 		ret = -EINVAL;
176 	else
177 		ret = extcon_set_state(edev, state);
178 
179 	if (ret < 0)
180 		return ret;
181 
182 	return count;
183 }
184 static DEVICE_ATTR_RW(state);
185 
186 static ssize_t name_show(struct device *dev, struct device_attribute *attr,
187 		char *buf)
188 {
189 	struct extcon_dev *edev = dev_get_drvdata(dev);
190 
191 	/* Optional callback given by the user */
192 	if (edev->print_name) {
193 		int ret = edev->print_name(edev, buf);
194 
195 		if (ret >= 0)
196 			return ret;
197 	}
198 
199 	return sprintf(buf, "%s\n", edev->name);
200 }
201 static DEVICE_ATTR_RO(name);
202 
203 static ssize_t cable_name_show(struct device *dev,
204 			       struct device_attribute *attr, char *buf)
205 {
206 	struct extcon_cable *cable = container_of(attr, struct extcon_cable,
207 						  attr_name);
208 	int i = cable->cable_index;
209 
210 	return sprintf(buf, "%s\n",
211 			extcon_name[cable->edev->supported_cable[i]]);
212 }
213 
214 static ssize_t cable_state_show(struct device *dev,
215 				struct device_attribute *attr, char *buf)
216 {
217 	struct extcon_cable *cable = container_of(attr, struct extcon_cable,
218 						  attr_state);
219 
220 	return sprintf(buf, "%d\n",
221 		       extcon_get_cable_state_(cable->edev,
222 					       cable->cable_index));
223 }
224 
225 /**
226  * extcon_update_state() - Update the cable attach states of the extcon device
227  *			   only for the masked bits.
228  * @edev:	the extcon device
229  * @mask:	the bit mask to designate updated bits.
230  * @state:	new cable attach status for @edev
231  *
232  * Changing the state sends uevent with environment variable containing
233  * the name of extcon device (envp[0]) and the state output (envp[1]).
234  * Tizen uses this format for extcon device to get events from ports.
235  * Android uses this format as well.
236  *
237  * Note that the notifier provides which bits are changed in the state
238  * variable with the val parameter (second) to the callback.
239  */
240 int extcon_update_state(struct extcon_dev *edev, u32 mask, u32 state)
241 {
242 	char name_buf[120];
243 	char state_buf[120];
244 	char *prop_buf;
245 	char *envp[3];
246 	int env_offset = 0;
247 	int length;
248 	unsigned long flags;
249 
250 	spin_lock_irqsave(&edev->lock, flags);
251 
252 	if (edev->state != ((edev->state & ~mask) | (state & mask))) {
253 		u32 old_state = edev->state;
254 
255 		if (check_mutually_exclusive(edev, (edev->state & ~mask) |
256 						   (state & mask))) {
257 			spin_unlock_irqrestore(&edev->lock, flags);
258 			return -EPERM;
259 		}
260 
261 		edev->state &= ~mask;
262 		edev->state |= state & mask;
263 
264 		raw_notifier_call_chain(&edev->nh, old_state, edev);
265 		/* This could be in interrupt handler */
266 		prop_buf = (char *)get_zeroed_page(GFP_ATOMIC);
267 		if (prop_buf) {
268 			length = name_show(&edev->dev, NULL, prop_buf);
269 			if (length > 0) {
270 				if (prop_buf[length - 1] == '\n')
271 					prop_buf[length - 1] = 0;
272 				snprintf(name_buf, sizeof(name_buf),
273 					"NAME=%s", prop_buf);
274 				envp[env_offset++] = name_buf;
275 			}
276 			length = state_show(&edev->dev, NULL, prop_buf);
277 			if (length > 0) {
278 				if (prop_buf[length - 1] == '\n')
279 					prop_buf[length - 1] = 0;
280 				snprintf(state_buf, sizeof(state_buf),
281 					"STATE=%s", prop_buf);
282 				envp[env_offset++] = state_buf;
283 			}
284 			envp[env_offset] = NULL;
285 			/* Unlock early before uevent */
286 			spin_unlock_irqrestore(&edev->lock, flags);
287 
288 			kobject_uevent_env(&edev->dev.kobj, KOBJ_CHANGE, envp);
289 			free_page((unsigned long)prop_buf);
290 		} else {
291 			/* Unlock early before uevent */
292 			spin_unlock_irqrestore(&edev->lock, flags);
293 
294 			dev_err(&edev->dev, "out of memory in extcon_set_state\n");
295 			kobject_uevent(&edev->dev.kobj, KOBJ_CHANGE);
296 		}
297 	} else {
298 		/* No changes */
299 		spin_unlock_irqrestore(&edev->lock, flags);
300 	}
301 
302 	return 0;
303 }
304 EXPORT_SYMBOL_GPL(extcon_update_state);
305 
306 /**
307  * extcon_set_state() - Set the cable attach states of the extcon device.
308  * @edev:	the extcon device
309  * @state:	new cable attach status for @edev
310  *
311  * Note that notifier provides which bits are changed in the state
312  * variable with the val parameter (second) to the callback.
313  */
314 int extcon_set_state(struct extcon_dev *edev, u32 state)
315 {
316 	return extcon_update_state(edev, 0xffffffff, state);
317 }
318 EXPORT_SYMBOL_GPL(extcon_set_state);
319 
320 /**
321  * extcon_get_cable_state_() - Get the status of a specific cable.
322  * @edev:	the extcon device that has the cable.
323  * @id:		the unique id of each external connector in extcon enumeration.
324  */
325 int extcon_get_cable_state_(struct extcon_dev *edev, const enum extcon id)
326 {
327 	int index;
328 
329 	index = find_cable_index_by_id(edev, id);
330 	if (index < 0)
331 		return index;
332 
333 	if (edev->max_supported && edev->max_supported <= index)
334 		return -EINVAL;
335 
336 	return !!(edev->state & (1 << index));
337 }
338 EXPORT_SYMBOL_GPL(extcon_get_cable_state_);
339 
340 /**
341  * extcon_get_cable_state() - Get the status of a specific cable.
342  * @edev:	the extcon device that has the cable.
343  * @cable_name:	cable name.
344  *
345  * Note that this is slower than extcon_get_cable_state_.
346  */
347 int extcon_get_cable_state(struct extcon_dev *edev, const char *cable_name)
348 {
349 	return extcon_get_cable_state_(edev, find_cable_index_by_name
350 						(edev, cable_name));
351 }
352 EXPORT_SYMBOL_GPL(extcon_get_cable_state);
353 
354 /**
355  * extcon_set_cable_state_() - Set the status of a specific cable.
356  * @edev:		the extcon device that has the cable.
357  * @id:			the unique id of each external connector
358  *			in extcon enumeration.
359  * @state:		the new cable status. The default semantics is
360  *			true: attached / false: detached.
361  */
362 int extcon_set_cable_state_(struct extcon_dev *edev, enum extcon id,
363 				bool cable_state)
364 {
365 	u32 state;
366 	int index;
367 
368 	index = find_cable_index_by_id(edev, id);
369 	if (index < 0)
370 		return index;
371 
372 	if (edev->max_supported && edev->max_supported <= index)
373 		return -EINVAL;
374 
375 	state = cable_state ? (1 << index) : 0;
376 	return extcon_update_state(edev, 1 << index, state);
377 }
378 EXPORT_SYMBOL_GPL(extcon_set_cable_state_);
379 
380 /**
381  * extcon_set_cable_state() - Set the status of a specific cable.
382  * @edev:		the extcon device that has the cable.
383  * @cable_name:		cable name.
384  * @cable_state:	the new cable status. The default semantics is
385  *			true: attached / false: detached.
386  *
387  * Note that this is slower than extcon_set_cable_state_.
388  */
389 int extcon_set_cable_state(struct extcon_dev *edev,
390 			const char *cable_name, bool cable_state)
391 {
392 	return extcon_set_cable_state_(edev, find_cable_index_by_name
393 					(edev, cable_name), cable_state);
394 }
395 EXPORT_SYMBOL_GPL(extcon_set_cable_state);
396 
397 /**
398  * extcon_get_extcon_dev() - Get the extcon device instance from the name
399  * @extcon_name:	The extcon name provided with extcon_dev_register()
400  */
401 struct extcon_dev *extcon_get_extcon_dev(const char *extcon_name)
402 {
403 	struct extcon_dev *sd;
404 
405 	mutex_lock(&extcon_dev_list_lock);
406 	list_for_each_entry(sd, &extcon_dev_list, entry) {
407 		if (!strcmp(sd->name, extcon_name))
408 			goto out;
409 	}
410 	sd = NULL;
411 out:
412 	mutex_unlock(&extcon_dev_list_lock);
413 	return sd;
414 }
415 EXPORT_SYMBOL_GPL(extcon_get_extcon_dev);
416 
417 static int _call_per_cable(struct notifier_block *nb, unsigned long val,
418 			   void *ptr)
419 {
420 	struct extcon_specific_cable_nb *obj = container_of(nb,
421 			struct extcon_specific_cable_nb, internal_nb);
422 	struct extcon_dev *edev = ptr;
423 
424 	if ((val & (1 << obj->cable_index)) !=
425 	    (edev->state & (1 << obj->cable_index))) {
426 		bool cable_state = true;
427 
428 		obj->previous_value = val;
429 
430 		if (val & (1 << obj->cable_index))
431 			cable_state = false;
432 
433 		return obj->user_nb->notifier_call(obj->user_nb,
434 				cable_state, ptr);
435 	}
436 
437 	return NOTIFY_OK;
438 }
439 
440 /**
441  * extcon_register_interest() - Register a notifier for a state change of a
442  *				specific cable, not an entier set of cables of a
443  *				extcon device.
444  * @obj:		an empty extcon_specific_cable_nb object to be returned.
445  * @extcon_name:	the name of extcon device.
446  *			if NULL, extcon_register_interest will register
447  *			every cable with the target cable_name given.
448  * @cable_name:		the target cable name.
449  * @nb:			the notifier block to get notified.
450  *
451  * Provide an empty extcon_specific_cable_nb. extcon_register_interest() sets
452  * the struct for you.
453  *
454  * extcon_register_interest is a helper function for those who want to get
455  * notification for a single specific cable's status change. If a user wants
456  * to get notification for any changes of all cables of a extcon device,
457  * he/she should use the general extcon_register_notifier().
458  *
459  * Note that the second parameter given to the callback of nb (val) is
460  * "old_state", not the current state. The current state can be retrieved
461  * by looking at the third pameter (edev pointer)'s state value.
462  */
463 int extcon_register_interest(struct extcon_specific_cable_nb *obj,
464 			     const char *extcon_name, const char *cable_name,
465 			     struct notifier_block *nb)
466 {
467 	unsigned long flags;
468 	int ret;
469 
470 	if (!obj || !cable_name || !nb)
471 		return -EINVAL;
472 
473 	if (extcon_name) {
474 		obj->edev = extcon_get_extcon_dev(extcon_name);
475 		if (!obj->edev)
476 			return -ENODEV;
477 
478 		obj->cable_index = find_cable_index_by_name(obj->edev,
479 							cable_name);
480 		if (obj->cable_index < 0)
481 			return obj->cable_index;
482 
483 		obj->user_nb = nb;
484 
485 		obj->internal_nb.notifier_call = _call_per_cable;
486 
487 		spin_lock_irqsave(&obj->edev->lock, flags);
488 		ret = raw_notifier_chain_register(&obj->edev->nh,
489 						  &obj->internal_nb);
490 		spin_unlock_irqrestore(&obj->edev->lock, flags);
491 	} else {
492 		struct class_dev_iter iter;
493 		struct extcon_dev *extd;
494 		struct device *dev;
495 
496 		if (!extcon_class)
497 			return -ENODEV;
498 		class_dev_iter_init(&iter, extcon_class, NULL, NULL);
499 		while ((dev = class_dev_iter_next(&iter))) {
500 			extd = dev_get_drvdata(dev);
501 
502 			if (find_cable_index_by_name(extd, cable_name) < 0)
503 				continue;
504 
505 			class_dev_iter_exit(&iter);
506 			return extcon_register_interest(obj, extd->name,
507 						cable_name, nb);
508 		}
509 
510 		ret = -ENODEV;
511 	}
512 
513 	return ret;
514 }
515 EXPORT_SYMBOL_GPL(extcon_register_interest);
516 
517 /**
518  * extcon_unregister_interest() - Unregister the notifier registered by
519  *				  extcon_register_interest().
520  * @obj:	the extcon_specific_cable_nb object returned by
521  *		extcon_register_interest().
522  */
523 int extcon_unregister_interest(struct extcon_specific_cable_nb *obj)
524 {
525 	unsigned long flags;
526 	int ret;
527 
528 	if (!obj)
529 		return -EINVAL;
530 
531 	spin_lock_irqsave(&obj->edev->lock, flags);
532 	ret = raw_notifier_chain_unregister(&obj->edev->nh, &obj->internal_nb);
533 	spin_unlock_irqrestore(&obj->edev->lock, flags);
534 
535 	return ret;
536 }
537 EXPORT_SYMBOL_GPL(extcon_unregister_interest);
538 
539 /**
540  * extcon_register_notifier() - Register a notifiee to get notified by
541  *				any attach status changes from the extcon.
542  * @edev:	the extcon device.
543  * @nb:		a notifier block to be registered.
544  *
545  * Note that the second parameter given to the callback of nb (val) is
546  * "old_state", not the current state. The current state can be retrieved
547  * by looking at the third pameter (edev pointer)'s state value.
548  */
549 int extcon_register_notifier(struct extcon_dev *edev,
550 			struct notifier_block *nb)
551 {
552 	unsigned long flags;
553 	int ret;
554 
555 	spin_lock_irqsave(&edev->lock, flags);
556 	ret = raw_notifier_chain_register(&edev->nh, nb);
557 	spin_unlock_irqrestore(&edev->lock, flags);
558 
559 	return ret;
560 }
561 EXPORT_SYMBOL_GPL(extcon_register_notifier);
562 
563 /**
564  * extcon_unregister_notifier() - Unregister a notifiee from the extcon device.
565  * @edev:	the extcon device.
566  * @nb:		a registered notifier block to be unregistered.
567  */
568 int extcon_unregister_notifier(struct extcon_dev *edev,
569 			struct notifier_block *nb)
570 {
571 	unsigned long flags;
572 	int ret;
573 
574 	spin_lock_irqsave(&edev->lock, flags);
575 	ret = raw_notifier_chain_unregister(&edev->nh, nb);
576 	spin_unlock_irqrestore(&edev->lock, flags);
577 
578 	return ret;
579 }
580 EXPORT_SYMBOL_GPL(extcon_unregister_notifier);
581 
582 static struct attribute *extcon_attrs[] = {
583 	&dev_attr_state.attr,
584 	&dev_attr_name.attr,
585 	NULL,
586 };
587 ATTRIBUTE_GROUPS(extcon);
588 
589 static int create_extcon_class(void)
590 {
591 	if (!extcon_class) {
592 		extcon_class = class_create(THIS_MODULE, "extcon");
593 		if (IS_ERR(extcon_class))
594 			return PTR_ERR(extcon_class);
595 		extcon_class->dev_groups = extcon_groups;
596 
597 #if defined(CONFIG_ANDROID)
598 		switch_class = class_compat_register("switch");
599 		if (WARN(!switch_class, "cannot allocate"))
600 			return -ENOMEM;
601 #endif /* CONFIG_ANDROID */
602 	}
603 
604 	return 0;
605 }
606 
607 static void extcon_dev_release(struct device *dev)
608 {
609 }
610 
611 static const char *muex_name = "mutually_exclusive";
612 static void dummy_sysfs_dev_release(struct device *dev)
613 {
614 }
615 
616 /*
617  * extcon_dev_allocate() - Allocate the memory of extcon device.
618  * @supported_cable:	Array of supported extcon ending with EXTCON_NONE.
619  *			If supported_cable is NULL, cable name related APIs
620  *			are disabled.
621  *
622  * This function allocates the memory for extcon device without allocating
623  * memory in each extcon provider driver and initialize default setting for
624  * extcon device.
625  *
626  * Return the pointer of extcon device if success or ERR_PTR(err) if fail
627  */
628 struct extcon_dev *extcon_dev_allocate(const enum extcon *supported_cable)
629 {
630 	struct extcon_dev *edev;
631 
632 	edev = kzalloc(sizeof(*edev), GFP_KERNEL);
633 	if (!edev)
634 		return ERR_PTR(-ENOMEM);
635 
636 	edev->max_supported = 0;
637 	edev->supported_cable = supported_cable;
638 
639 	return edev;
640 }
641 
642 /*
643  * extcon_dev_free() - Free the memory of extcon device.
644  * @edev:	the extcon device to free
645  */
646 void extcon_dev_free(struct extcon_dev *edev)
647 {
648 	kfree(edev);
649 }
650 EXPORT_SYMBOL_GPL(extcon_dev_free);
651 
652 static int devm_extcon_dev_match(struct device *dev, void *res, void *data)
653 {
654 	struct extcon_dev **r = res;
655 
656 	if (WARN_ON(!r || !*r))
657 		return 0;
658 
659 	return *r == data;
660 }
661 
662 static void devm_extcon_dev_release(struct device *dev, void *res)
663 {
664 	extcon_dev_free(*(struct extcon_dev **)res);
665 }
666 
667 /**
668  * devm_extcon_dev_allocate - Allocate managed extcon device
669  * @dev:		device owning the extcon device being created
670  * @supported_cable:	Array of supported extcon ending with EXTCON_NONE.
671  *			If supported_cable is NULL, cable name related APIs
672  *			are disabled.
673  *
674  * This function manages automatically the memory of extcon device using device
675  * resource management and simplify the control of freeing the memory of extcon
676  * device.
677  *
678  * Returns the pointer memory of allocated extcon_dev if success
679  * or ERR_PTR(err) if fail
680  */
681 struct extcon_dev *devm_extcon_dev_allocate(struct device *dev,
682 					const enum extcon *supported_cable)
683 {
684 	struct extcon_dev **ptr, *edev;
685 
686 	ptr = devres_alloc(devm_extcon_dev_release, sizeof(*ptr), GFP_KERNEL);
687 	if (!ptr)
688 		return ERR_PTR(-ENOMEM);
689 
690 	edev = extcon_dev_allocate(supported_cable);
691 	if (IS_ERR(edev)) {
692 		devres_free(ptr);
693 		return edev;
694 	}
695 
696 	edev->dev.parent = dev;
697 
698 	*ptr = edev;
699 	devres_add(dev, ptr);
700 
701 	return edev;
702 }
703 EXPORT_SYMBOL_GPL(devm_extcon_dev_allocate);
704 
705 void devm_extcon_dev_free(struct device *dev, struct extcon_dev *edev)
706 {
707 	WARN_ON(devres_release(dev, devm_extcon_dev_release,
708 			       devm_extcon_dev_match, edev));
709 }
710 EXPORT_SYMBOL_GPL(devm_extcon_dev_free);
711 
712 /**
713  * extcon_dev_register() - Register a new extcon device
714  * @edev	: the new extcon device (should be allocated before calling)
715  *
716  * Among the members of edev struct, please set the "user initializing data"
717  * in any case and set the "optional callbacks" if required. However, please
718  * do not set the values of "internal data", which are initialized by
719  * this function.
720  */
721 int extcon_dev_register(struct extcon_dev *edev)
722 {
723 	int ret, index = 0;
724 	static atomic_t edev_no = ATOMIC_INIT(-1);
725 
726 	if (!extcon_class) {
727 		ret = create_extcon_class();
728 		if (ret < 0)
729 			return ret;
730 	}
731 
732 	if (!edev->supported_cable)
733 		return -EINVAL;
734 
735 	for (; edev->supported_cable[index] != EXTCON_NONE; index++);
736 
737 	edev->max_supported = index;
738 	if (index > SUPPORTED_CABLE_MAX) {
739 		dev_err(&edev->dev,
740 			"exceed the maximum number of supported cables\n");
741 		return -EINVAL;
742 	}
743 
744 	edev->dev.class = extcon_class;
745 	edev->dev.release = extcon_dev_release;
746 
747 	edev->name = dev_name(edev->dev.parent);
748 	if (IS_ERR_OR_NULL(edev->name)) {
749 		dev_err(&edev->dev,
750 			"extcon device name is null\n");
751 		return -EINVAL;
752 	}
753 	dev_set_name(&edev->dev, "extcon%lu",
754 			(unsigned long)atomic_inc_return(&edev_no));
755 
756 	if (edev->max_supported) {
757 		char buf[10];
758 		char *str;
759 		struct extcon_cable *cable;
760 
761 		edev->cables = kzalloc(sizeof(struct extcon_cable) *
762 				       edev->max_supported, GFP_KERNEL);
763 		if (!edev->cables) {
764 			ret = -ENOMEM;
765 			goto err_sysfs_alloc;
766 		}
767 		for (index = 0; index < edev->max_supported; index++) {
768 			cable = &edev->cables[index];
769 
770 			snprintf(buf, 10, "cable.%d", index);
771 			str = kzalloc(sizeof(char) * (strlen(buf) + 1),
772 				      GFP_KERNEL);
773 			if (!str) {
774 				for (index--; index >= 0; index--) {
775 					cable = &edev->cables[index];
776 					kfree(cable->attr_g.name);
777 				}
778 				ret = -ENOMEM;
779 
780 				goto err_alloc_cables;
781 			}
782 			strcpy(str, buf);
783 
784 			cable->edev = edev;
785 			cable->cable_index = index;
786 			cable->attrs[0] = &cable->attr_name.attr;
787 			cable->attrs[1] = &cable->attr_state.attr;
788 			cable->attrs[2] = NULL;
789 			cable->attr_g.name = str;
790 			cable->attr_g.attrs = cable->attrs;
791 
792 			sysfs_attr_init(&cable->attr_name.attr);
793 			cable->attr_name.attr.name = "name";
794 			cable->attr_name.attr.mode = 0444;
795 			cable->attr_name.show = cable_name_show;
796 
797 			sysfs_attr_init(&cable->attr_state.attr);
798 			cable->attr_state.attr.name = "state";
799 			cable->attr_state.attr.mode = 0444;
800 			cable->attr_state.show = cable_state_show;
801 		}
802 	}
803 
804 	if (edev->max_supported && edev->mutually_exclusive) {
805 		char buf[80];
806 		char *name;
807 
808 		/* Count the size of mutually_exclusive array */
809 		for (index = 0; edev->mutually_exclusive[index]; index++)
810 			;
811 
812 		edev->attrs_muex = kzalloc(sizeof(struct attribute *) *
813 					   (index + 1), GFP_KERNEL);
814 		if (!edev->attrs_muex) {
815 			ret = -ENOMEM;
816 			goto err_muex;
817 		}
818 
819 		edev->d_attrs_muex = kzalloc(sizeof(struct device_attribute) *
820 					     index, GFP_KERNEL);
821 		if (!edev->d_attrs_muex) {
822 			ret = -ENOMEM;
823 			kfree(edev->attrs_muex);
824 			goto err_muex;
825 		}
826 
827 		for (index = 0; edev->mutually_exclusive[index]; index++) {
828 			sprintf(buf, "0x%x", edev->mutually_exclusive[index]);
829 			name = kzalloc(sizeof(char) * (strlen(buf) + 1),
830 				       GFP_KERNEL);
831 			if (!name) {
832 				for (index--; index >= 0; index--) {
833 					kfree(edev->d_attrs_muex[index].attr.
834 					      name);
835 				}
836 				kfree(edev->d_attrs_muex);
837 				kfree(edev->attrs_muex);
838 				ret = -ENOMEM;
839 				goto err_muex;
840 			}
841 			strcpy(name, buf);
842 			sysfs_attr_init(&edev->d_attrs_muex[index].attr);
843 			edev->d_attrs_muex[index].attr.name = name;
844 			edev->d_attrs_muex[index].attr.mode = 0000;
845 			edev->attrs_muex[index] = &edev->d_attrs_muex[index]
846 							.attr;
847 		}
848 		edev->attr_g_muex.name = muex_name;
849 		edev->attr_g_muex.attrs = edev->attrs_muex;
850 
851 	}
852 
853 	if (edev->max_supported) {
854 		edev->extcon_dev_type.groups =
855 			kzalloc(sizeof(struct attribute_group *) *
856 				(edev->max_supported + 2), GFP_KERNEL);
857 		if (!edev->extcon_dev_type.groups) {
858 			ret = -ENOMEM;
859 			goto err_alloc_groups;
860 		}
861 
862 		edev->extcon_dev_type.name = dev_name(&edev->dev);
863 		edev->extcon_dev_type.release = dummy_sysfs_dev_release;
864 
865 		for (index = 0; index < edev->max_supported; index++)
866 			edev->extcon_dev_type.groups[index] =
867 				&edev->cables[index].attr_g;
868 		if (edev->mutually_exclusive)
869 			edev->extcon_dev_type.groups[index] =
870 				&edev->attr_g_muex;
871 
872 		edev->dev.type = &edev->extcon_dev_type;
873 	}
874 
875 	ret = device_register(&edev->dev);
876 	if (ret) {
877 		put_device(&edev->dev);
878 		goto err_dev;
879 	}
880 #if defined(CONFIG_ANDROID)
881 	if (switch_class)
882 		ret = class_compat_create_link(switch_class, &edev->dev, NULL);
883 #endif /* CONFIG_ANDROID */
884 
885 	spin_lock_init(&edev->lock);
886 
887 	RAW_INIT_NOTIFIER_HEAD(&edev->nh);
888 
889 	dev_set_drvdata(&edev->dev, edev);
890 	edev->state = 0;
891 
892 	mutex_lock(&extcon_dev_list_lock);
893 	list_add(&edev->entry, &extcon_dev_list);
894 	mutex_unlock(&extcon_dev_list_lock);
895 
896 	return 0;
897 
898 err_dev:
899 	if (edev->max_supported)
900 		kfree(edev->extcon_dev_type.groups);
901 err_alloc_groups:
902 	if (edev->max_supported && edev->mutually_exclusive) {
903 		for (index = 0; edev->mutually_exclusive[index]; index++)
904 			kfree(edev->d_attrs_muex[index].attr.name);
905 		kfree(edev->d_attrs_muex);
906 		kfree(edev->attrs_muex);
907 	}
908 err_muex:
909 	for (index = 0; index < edev->max_supported; index++)
910 		kfree(edev->cables[index].attr_g.name);
911 err_alloc_cables:
912 	if (edev->max_supported)
913 		kfree(edev->cables);
914 err_sysfs_alloc:
915 	return ret;
916 }
917 EXPORT_SYMBOL_GPL(extcon_dev_register);
918 
919 /**
920  * extcon_dev_unregister() - Unregister the extcon device.
921  * @edev:	the extcon device instance to be unregistered.
922  *
923  * Note that this does not call kfree(edev) because edev was not allocated
924  * by this class.
925  */
926 void extcon_dev_unregister(struct extcon_dev *edev)
927 {
928 	int index;
929 
930 	mutex_lock(&extcon_dev_list_lock);
931 	list_del(&edev->entry);
932 	mutex_unlock(&extcon_dev_list_lock);
933 
934 	if (IS_ERR_OR_NULL(get_device(&edev->dev))) {
935 		dev_err(&edev->dev, "Failed to unregister extcon_dev (%s)\n",
936 				dev_name(&edev->dev));
937 		return;
938 	}
939 
940 	device_unregister(&edev->dev);
941 
942 	if (edev->mutually_exclusive && edev->max_supported) {
943 		for (index = 0; edev->mutually_exclusive[index];
944 				index++)
945 			kfree(edev->d_attrs_muex[index].attr.name);
946 		kfree(edev->d_attrs_muex);
947 		kfree(edev->attrs_muex);
948 	}
949 
950 	for (index = 0; index < edev->max_supported; index++)
951 		kfree(edev->cables[index].attr_g.name);
952 
953 	if (edev->max_supported) {
954 		kfree(edev->extcon_dev_type.groups);
955 		kfree(edev->cables);
956 	}
957 
958 #if defined(CONFIG_ANDROID)
959 	if (switch_class)
960 		class_compat_remove_link(switch_class, &edev->dev, NULL);
961 #endif
962 	put_device(&edev->dev);
963 }
964 EXPORT_SYMBOL_GPL(extcon_dev_unregister);
965 
966 static void devm_extcon_dev_unreg(struct device *dev, void *res)
967 {
968 	extcon_dev_unregister(*(struct extcon_dev **)res);
969 }
970 
971 /**
972  * devm_extcon_dev_register() - Resource-managed extcon_dev_register()
973  * @dev:	device to allocate extcon device
974  * @edev:	the new extcon device to register
975  *
976  * Managed extcon_dev_register() function. If extcon device is attached with
977  * this function, that extcon device is automatically unregistered on driver
978  * detach. Internally this function calls extcon_dev_register() function.
979  * To get more information, refer that function.
980  *
981  * If extcon device is registered with this function and the device needs to be
982  * unregistered separately, devm_extcon_dev_unregister() should be used.
983  *
984  * Returns 0 if success or negaive error number if failure.
985  */
986 int devm_extcon_dev_register(struct device *dev, struct extcon_dev *edev)
987 {
988 	struct extcon_dev **ptr;
989 	int ret;
990 
991 	ptr = devres_alloc(devm_extcon_dev_unreg, sizeof(*ptr), GFP_KERNEL);
992 	if (!ptr)
993 		return -ENOMEM;
994 
995 	ret = extcon_dev_register(edev);
996 	if (ret) {
997 		devres_free(ptr);
998 		return ret;
999 	}
1000 
1001 	*ptr = edev;
1002 	devres_add(dev, ptr);
1003 
1004 	return 0;
1005 }
1006 EXPORT_SYMBOL_GPL(devm_extcon_dev_register);
1007 
1008 /**
1009  * devm_extcon_dev_unregister() - Resource-managed extcon_dev_unregister()
1010  * @dev:	device the extcon belongs to
1011  * @edev:	the extcon device to unregister
1012  *
1013  * Unregister extcon device that is registered with devm_extcon_dev_register()
1014  * function.
1015  */
1016 void devm_extcon_dev_unregister(struct device *dev, struct extcon_dev *edev)
1017 {
1018 	WARN_ON(devres_release(dev, devm_extcon_dev_unreg,
1019 			       devm_extcon_dev_match, edev));
1020 }
1021 EXPORT_SYMBOL_GPL(devm_extcon_dev_unregister);
1022 
1023 #ifdef CONFIG_OF
1024 /*
1025  * extcon_get_edev_by_phandle - Get the extcon device from devicetree
1026  * @dev - instance to the given device
1027  * @index - index into list of extcon_dev
1028  *
1029  * return the instance of extcon device
1030  */
1031 struct extcon_dev *extcon_get_edev_by_phandle(struct device *dev, int index)
1032 {
1033 	struct device_node *node;
1034 	struct extcon_dev *edev;
1035 
1036 	if (!dev->of_node) {
1037 		dev_err(dev, "device does not have a device node entry\n");
1038 		return ERR_PTR(-EINVAL);
1039 	}
1040 
1041 	node = of_parse_phandle(dev->of_node, "extcon", index);
1042 	if (!node) {
1043 		dev_err(dev, "failed to get phandle in %s node\n",
1044 			dev->of_node->full_name);
1045 		return ERR_PTR(-ENODEV);
1046 	}
1047 
1048 	mutex_lock(&extcon_dev_list_lock);
1049 	list_for_each_entry(edev, &extcon_dev_list, entry) {
1050 		if (edev->dev.parent && edev->dev.parent->of_node == node) {
1051 			mutex_unlock(&extcon_dev_list_lock);
1052 			return edev;
1053 		}
1054 	}
1055 	mutex_unlock(&extcon_dev_list_lock);
1056 
1057 	return ERR_PTR(-EPROBE_DEFER);
1058 }
1059 #else
1060 struct extcon_dev *extcon_get_edev_by_phandle(struct device *dev, int index)
1061 {
1062 	return ERR_PTR(-ENOSYS);
1063 }
1064 #endif /* CONFIG_OF */
1065 EXPORT_SYMBOL_GPL(extcon_get_edev_by_phandle);
1066 
1067 /**
1068  * extcon_get_edev_name() - Get the name of the extcon device.
1069  * @edev:	the extcon device
1070  */
1071 const char *extcon_get_edev_name(struct extcon_dev *edev)
1072 {
1073 	return !edev ? NULL : edev->name;
1074 }
1075 
1076 static int __init extcon_class_init(void)
1077 {
1078 	return create_extcon_class();
1079 }
1080 module_init(extcon_class_init);
1081 
1082 static void __exit extcon_class_exit(void)
1083 {
1084 #if defined(CONFIG_ANDROID)
1085 	class_compat_unregister(switch_class);
1086 #endif
1087 	class_destroy(extcon_class);
1088 }
1089 module_exit(extcon_class_exit);
1090 
1091 MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
1092 MODULE_AUTHOR("Mike Lockwood <lockwood@android.com>");
1093 MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>");
1094 MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
1095 MODULE_DESCRIPTION("External connector (extcon) class driver");
1096 MODULE_LICENSE("GPL");
1097