Lines Matching +full:usb +full:- +full:sdp
1 // SPDX-License-Identifier: GPL-2.0-only
3 * drivers/extcon/extcon.c - External Connector (extcon) framework.
44 /* USB external connector */
48 .name = "USB",
53 .name = "USB-HOST",
60 .name = "SDP",
80 .name = "FAST-CHARGER",
85 .name = "SLOW-CHARGER",
112 .name = "LINE-IN",
117 .name = "LINE-OUT",
122 .name = "VIDEO-IN",
127 .name = "VIDEO-OUT",
132 .name = "SPDIF-IN",
137 .name = "SPDIF-OUT",
203 * struct extcon_cable - An internal data for an external connector.
210 * @usb_propval: the array of USB connector properties
214 * @usb_bits: the bit array of the USB connector property capabilities
250 if (!edev->mutually_exclusive)
253 for (i = 0; edev->mutually_exclusive[i]; i++) {
255 u32 correspondants = new_state & edev->mutually_exclusive[i];
270 /* Find the index of extcon cable in edev->supported_cable */
271 for (i = 0; i < edev->max_supported; i++) {
272 if (edev->supported_cable[i] == id)
276 return -EINVAL;
291 return -EINVAL;
297 return !!(edev->state & BIT(index));
303 int state = !!(edev->state & BIT(index));
331 cable = &edev->cables[index];
335 ret = test_bit(prop - EXTCON_PROP_USB_MIN, cable->usb_bits);
338 ret = test_bit(prop - EXTCON_PROP_CHG_MIN, cable->chg_bits);
341 ret = test_bit(prop - EXTCON_PROP_JACK_MIN, cable->jack_bits);
344 ret = test_bit(prop - EXTCON_PROP_DISP_MIN, cable->disp_bits);
347 ret = -EINVAL;
356 struct extcon_cable *cable = &edev->cables[index];
359 memset(cable->usb_propval, 0, sizeof(cable->usb_propval));
361 memset(cable->chg_propval, 0, sizeof(cable->chg_propval));
363 memset(cable->jack_propval, 0, sizeof(cable->jack_propval));
365 memset(cable->disp_propval, 0, sizeof(cable->disp_propval));
374 if (edev->max_supported == 0)
375 return sysfs_emit(buf, "%u\n", edev->state);
377 for (i = 0; i < edev->max_supported; i++) {
379 extcon_info[edev->supported_cable[i]].name,
380 !!(edev->state & BIT(i)));
392 return sysfs_emit(buf, "%s\n", edev->name);
401 int i = cable->cable_index;
404 extcon_info[cable->edev->supported_cable[i]].name);
413 int i = cable->cable_index;
416 extcon_get_state(cable->edev, cable->edev->supported_cable[i]));
420 * extcon_sync() - Synchronize the state for an external connector.
442 return -EINVAL;
448 spin_lock_irqsave(&edev->lock, flags);
449 state = !!(edev->state & BIT(index));
450 spin_unlock_irqrestore(&edev->lock, flags);
456 raw_notifier_call_chain(&edev->nh[index], state, edev);
462 raw_notifier_call_chain(&edev->nh_all, state, edev);
464 spin_lock_irqsave(&edev->lock, flags);
469 spin_unlock_irqrestore(&edev->lock, flags);
471 dev_err(&edev->dev, "out of memory in extcon_set_state\n");
472 kobject_uevent(&edev->dev.kobj, KOBJ_CHANGE);
474 return -ENOMEM;
477 length = name_show(&edev->dev, NULL, prop_buf);
479 if (prop_buf[length - 1] == '\n')
480 prop_buf[length - 1] = 0;
485 length = state_show(&edev->dev, NULL, prop_buf);
487 if (prop_buf[length - 1] == '\n')
488 prop_buf[length - 1] = 0;
495 spin_unlock_irqrestore(&edev->lock, flags);
496 kobject_uevent_env(&edev->dev.kobj, KOBJ_CHANGE, envp);
504 * extcon_get_state() - Get the state of an external connector.
516 return -EINVAL;
522 spin_lock_irqsave(&edev->lock, flags);
524 spin_unlock_irqrestore(&edev->lock, flags);
531 * extcon_set_state() - Set the state of an external connector.
549 return -EINVAL;
555 spin_lock_irqsave(&edev->lock, flags);
562 (edev->state & ~BIT(index)) | (state & BIT(index)))) {
563 ret = -EPERM;
576 edev->state |= BIT(index);
578 edev->state &= ~(BIT(index));
580 spin_unlock_irqrestore(&edev->lock, flags);
587 * extcon_set_state_sync() - Set the state of an external connector with sync.
611 * extcon_get_property() - Get the property value of an external connector.
635 return -EINVAL;
639 return -EINVAL;
646 spin_lock_irqsave(&edev->lock, flags);
650 spin_unlock_irqrestore(&edev->lock, flags);
651 return -EPERM;
660 spin_unlock_irqrestore(&edev->lock, flags);
664 cable = &edev->cables[index];
669 *prop_val = cable->usb_propval[prop - EXTCON_PROP_USB_MIN];
672 *prop_val = cable->chg_propval[prop - EXTCON_PROP_CHG_MIN];
675 *prop_val = cable->jack_propval[prop - EXTCON_PROP_JACK_MIN];
678 *prop_val = cable->disp_propval[prop - EXTCON_PROP_DISP_MIN];
681 ret = -EINVAL;
685 spin_unlock_irqrestore(&edev->lock, flags);
692 * extcon_set_property() - Set the property value of an external connector.
712 return -EINVAL;
716 return -EINVAL;
723 spin_lock_irqsave(&edev->lock, flags);
727 spin_unlock_irqrestore(&edev->lock, flags);
728 return -EPERM;
731 cable = &edev->cables[index];
736 cable->usb_propval[prop - EXTCON_PROP_USB_MIN] = prop_val;
739 cable->chg_propval[prop - EXTCON_PROP_CHG_MIN] = prop_val;
742 cable->jack_propval[prop - EXTCON_PROP_JACK_MIN] = prop_val;
745 cable->disp_propval[prop - EXTCON_PROP_DISP_MIN] = prop_val;
748 ret = -EINVAL;
752 spin_unlock_irqrestore(&edev->lock, flags);
759 * extcon_set_property_sync() - Set property of an external connector with sync.
786 * extcon_get_property_capability() - Get the capability of the property
800 return -EINVAL;
804 return -EINVAL;
816 * extcon_set_property_capability() - Set the capability of the property
835 return -EINVAL;
839 return -EINVAL;
850 cable = &edev->cables[index];
854 __set_bit(prop - EXTCON_PROP_USB_MIN, cable->usb_bits);
857 __set_bit(prop - EXTCON_PROP_CHG_MIN, cable->chg_bits);
860 __set_bit(prop - EXTCON_PROP_JACK_MIN, cable->jack_bits);
863 __set_bit(prop - EXTCON_PROP_DISP_MIN, cable->disp_bits);
866 ret = -EINVAL;
874 * extcon_get_extcon_dev() - Get the extcon device instance from the name.
878 * NOTE: This function returns -EPROBE_DEFER so it may only be called from
886 return ERR_PTR(-EINVAL);
890 if (!strcmp(sd->name, extcon_name))
893 sd = ERR_PTR(-EPROBE_DEFER);
901 * extcon_register_notifier() - Register a notifier block to get notified by
920 return -EINVAL;
926 spin_lock_irqsave(&edev->lock, flags);
927 ret = raw_notifier_chain_register(&edev->nh[idx], nb);
928 spin_unlock_irqrestore(&edev->lock, flags);
935 * extcon_unregister_notifier() - Unregister a notifier block from the extcon.
949 return -EINVAL;
955 spin_lock_irqsave(&edev->lock, flags);
956 ret = raw_notifier_chain_unregister(&edev->nh[idx], nb);
957 spin_unlock_irqrestore(&edev->lock, flags);
964 * extcon_register_notifier_all() - Register a notifier block for all connectors.
982 return -EINVAL;
984 spin_lock_irqsave(&edev->lock, flags);
985 ret = raw_notifier_chain_register(&edev->nh_all, nb);
986 spin_unlock_irqrestore(&edev->lock, flags);
993 * extcon_unregister_notifier_all() - Unregister a notifier block from extcon.
1006 return -EINVAL;
1008 spin_lock_irqsave(&edev->lock, flags);
1009 ret = raw_notifier_chain_unregister(&edev->nh_all, nb);
1010 spin_unlock_irqrestore(&edev->lock, flags);
1031 extcon_class->dev_groups = extcon_groups;
1046 * extcon_dev_allocate() - Allocate the memory of extcon device.
1061 return ERR_PTR(-EINVAL);
1065 return ERR_PTR(-ENOMEM);
1067 edev->max_supported = 0;
1068 edev->supported_cable = supported_cable;
1074 * extcon_dev_free() - Free the memory of extcon device.
1084 * extcon_alloc_cables() - alloc the cables for extcon device
1096 return -EINVAL;
1098 if (!edev->max_supported)
1101 edev->cables = kcalloc(edev->max_supported, sizeof(*edev->cables),
1103 if (!edev->cables)
1104 return -ENOMEM;
1106 for (index = 0; index < edev->max_supported; index++) {
1107 cable = &edev->cables[index];
1111 for (index--; index >= 0; index--) {
1112 cable = &edev->cables[index];
1113 kfree(cable->attr_g.name);
1116 kfree(edev->cables);
1117 return -ENOMEM;
1120 cable->edev = edev;
1121 cable->cable_index = index;
1122 cable->attrs[0] = &cable->attr_name.attr;
1123 cable->attrs[1] = &cable->attr_state.attr;
1124 cable->attrs[2] = NULL;
1125 cable->attr_g.name = str;
1126 cable->attr_g.attrs = cable->attrs;
1128 sysfs_attr_init(&cable->attr_name.attr);
1129 cable->attr_name.attr.name = "name";
1130 cable->attr_name.attr.mode = 0444;
1131 cable->attr_name.show = cable_name_show;
1133 sysfs_attr_init(&cable->attr_state.attr);
1134 cable->attr_state.attr.name = "state";
1135 cable->attr_state.attr.mode = 0444;
1136 cable->attr_state.show = cable_state_show;
1143 * extcon_alloc_muex() - alloc the mutual exclusive for extcon device
1154 return -EINVAL;
1156 if (!(edev->max_supported && edev->mutually_exclusive))
1160 for (index = 0; edev->mutually_exclusive[index]; index++)
1163 edev->attrs_muex = kcalloc(index + 1, sizeof(*edev->attrs_muex),
1165 if (!edev->attrs_muex)
1166 return -ENOMEM;
1168 edev->d_attrs_muex = kcalloc(index, sizeof(*edev->d_attrs_muex),
1170 if (!edev->d_attrs_muex) {
1171 kfree(edev->attrs_muex);
1172 return -ENOMEM;
1175 for (index = 0; edev->mutually_exclusive[index]; index++) {
1177 edev->mutually_exclusive[index]);
1179 for (index--; index >= 0; index--)
1180 kfree(edev->d_attrs_muex[index].attr.name);
1182 kfree(edev->d_attrs_muex);
1183 kfree(edev->attrs_muex);
1184 return -ENOMEM;
1186 sysfs_attr_init(&edev->d_attrs_muex[index].attr);
1187 edev->d_attrs_muex[index].attr.name = name;
1188 edev->d_attrs_muex[index].attr.mode = 0000;
1189 edev->attrs_muex[index] = &edev->d_attrs_muex[index].attr;
1191 edev->attr_g_muex.name = muex_name;
1192 edev->attr_g_muex.attrs = edev->attrs_muex;
1198 * extcon_alloc_groups() - alloc the groups for extcon device
1208 return -EINVAL;
1210 if (!edev->max_supported)
1213 edev->extcon_dev_type.groups = kcalloc(edev->max_supported + 2,
1214 sizeof(*edev->extcon_dev_type.groups),
1216 if (!edev->extcon_dev_type.groups)
1217 return -ENOMEM;
1219 edev->extcon_dev_type.name = dev_name(&edev->dev);
1220 edev->extcon_dev_type.release = dummy_sysfs_dev_release;
1222 for (index = 0; index < edev->max_supported; index++)
1223 edev->extcon_dev_type.groups[index] = &edev->cables[index].attr_g;
1225 if (edev->mutually_exclusive)
1226 edev->extcon_dev_type.groups[index] = &edev->attr_g_muex;
1228 edev->dev.type = &edev->extcon_dev_type;
1234 * extcon_dev_register() - Register an new extcon device
1255 if (!edev || !edev->supported_cable)
1256 return -EINVAL;
1258 for (index = 0; edev->supported_cable[index] != EXTCON_NONE; index++);
1260 edev->max_supported = index;
1262 dev_err(&edev->dev,
1264 return -EINVAL;
1267 edev->dev.class = extcon_class;
1268 edev->dev.release = extcon_dev_release;
1270 edev->name = dev_name(edev->dev.parent);
1271 if (IS_ERR_OR_NULL(edev->name)) {
1272 dev_err(&edev->dev,
1274 return -EINVAL;
1281 edev->id = ret;
1295 spin_lock_init(&edev->lock);
1296 if (edev->max_supported) {
1297 edev->nh = kcalloc(edev->max_supported, sizeof(*edev->nh),
1299 if (!edev->nh) {
1300 ret = -ENOMEM;
1305 for (index = 0; index < edev->max_supported; index++)
1306 RAW_INIT_NOTIFIER_HEAD(&edev->nh[index]);
1308 RAW_INIT_NOTIFIER_HEAD(&edev->nh_all);
1310 dev_set_drvdata(&edev->dev, edev);
1311 dev_set_name(&edev->dev, "extcon%d", edev->id);
1312 edev->state = 0;
1314 ret = device_register(&edev->dev);
1316 put_device(&edev->dev);
1321 list_add(&edev->entry, &extcon_dev_list);
1327 if (edev->max_supported)
1328 kfree(edev->nh);
1330 if (edev->max_supported)
1331 kfree(edev->extcon_dev_type.groups);
1333 if (edev->max_supported && edev->mutually_exclusive) {
1334 for (index = 0; edev->mutually_exclusive[index]; index++)
1335 kfree(edev->d_attrs_muex[index].attr.name);
1336 kfree(edev->d_attrs_muex);
1337 kfree(edev->attrs_muex);
1340 for (index = 0; index < edev->max_supported; index++)
1341 kfree(edev->cables[index].attr_g.name);
1342 if (edev->max_supported)
1343 kfree(edev->cables);
1345 ida_free(&extcon_dev_ids, edev->id);
1352 * extcon_dev_unregister() - Unregister the extcon device.
1366 list_del(&edev->entry);
1369 if (!get_device(&edev->dev)) {
1370 dev_err(&edev->dev, "Failed to unregister extcon_dev\n");
1374 ida_free(&extcon_dev_ids, edev->id);
1376 device_unregister(&edev->dev);
1378 if (edev->mutually_exclusive && edev->max_supported) {
1379 for (index = 0; edev->mutually_exclusive[index];
1381 kfree(edev->d_attrs_muex[index].attr.name);
1382 kfree(edev->d_attrs_muex);
1383 kfree(edev->attrs_muex);
1386 for (index = 0; index < edev->max_supported; index++)
1387 kfree(edev->cables[index].attr_g.name);
1389 if (edev->max_supported) {
1390 kfree(edev->extcon_dev_type.groups);
1391 kfree(edev->cables);
1392 kfree(edev->nh);
1395 put_device(&edev->dev);
1402 * extcon_find_edev_by_node - Find the extcon device from devicetree.
1413 if (edev->dev.parent && device_match_of_node(edev->dev.parent, node))
1415 edev = ERR_PTR(-EPROBE_DEFER);
1423 * extcon_get_edev_by_phandle - Get the extcon device from devicetree.
1436 return ERR_PTR(-EINVAL);
1442 return ERR_PTR(-ENODEV);
1455 return ERR_PTR(-ENOSYS);
1460 return ERR_PTR(-ENOSYS);
1469 * extcon_get_edev_name() - Get the name of the extcon device.
1474 return !edev ? NULL : edev->name;