0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/device.h>
0011 #include <linux/list.h>
0012 #include <linux/module.h>
0013 #include <linux/mutex.h>
0014 #include <linux/property.h>
0015 #include <linux/slab.h>
0016
0017 #include "class.h"
0018 #include "mux.h"
0019
0020 #define TYPEC_MUX_MAX_DEVS 3
0021
0022 struct typec_switch {
0023 struct typec_switch_dev *sw_devs[TYPEC_MUX_MAX_DEVS];
0024 unsigned int num_sw_devs;
0025 };
0026
0027 static int switch_fwnode_match(struct device *dev, const void *fwnode)
0028 {
0029 if (!is_typec_switch_dev(dev))
0030 return 0;
0031
0032 return dev_fwnode(dev) == fwnode;
0033 }
0034
0035 static void *typec_switch_match(struct fwnode_handle *fwnode, const char *id,
0036 void *data)
0037 {
0038 struct device *dev;
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048 if (id && !fwnode_property_present(fwnode, id))
0049 return NULL;
0050
0051
0052
0053
0054
0055
0056 dev = class_find_device(&typec_mux_class, NULL, fwnode,
0057 switch_fwnode_match);
0058
0059 return dev ? to_typec_switch_dev(dev) : ERR_PTR(-EPROBE_DEFER);
0060 }
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071 struct typec_switch *fwnode_typec_switch_get(struct fwnode_handle *fwnode)
0072 {
0073 struct typec_switch_dev *sw_devs[TYPEC_MUX_MAX_DEVS];
0074 struct typec_switch *sw;
0075 int count;
0076 int err;
0077 int i;
0078
0079 sw = kzalloc(sizeof(*sw), GFP_KERNEL);
0080 if (!sw)
0081 return ERR_PTR(-ENOMEM);
0082
0083 count = fwnode_connection_find_matches(fwnode, "orientation-switch", NULL,
0084 typec_switch_match,
0085 (void **)sw_devs,
0086 ARRAY_SIZE(sw_devs));
0087 if (count <= 0) {
0088 kfree(sw);
0089 return NULL;
0090 }
0091
0092 for (i = 0; i < count; i++) {
0093 if (IS_ERR(sw_devs[i])) {
0094 err = PTR_ERR(sw_devs[i]);
0095 goto put_sw_devs;
0096 }
0097 }
0098
0099 for (i = 0; i < count; i++) {
0100 WARN_ON(!try_module_get(sw_devs[i]->dev.parent->driver->owner));
0101 sw->sw_devs[i] = sw_devs[i];
0102 }
0103
0104 sw->num_sw_devs = count;
0105
0106 return sw;
0107
0108 put_sw_devs:
0109 for (i = 0; i < count; i++) {
0110 if (!IS_ERR(sw_devs[i]))
0111 put_device(&sw_devs[i]->dev);
0112 }
0113
0114 kfree(sw);
0115
0116 return ERR_PTR(err);
0117 }
0118 EXPORT_SYMBOL_GPL(fwnode_typec_switch_get);
0119
0120
0121
0122
0123
0124
0125
0126 void typec_switch_put(struct typec_switch *sw)
0127 {
0128 struct typec_switch_dev *sw_dev;
0129 unsigned int i;
0130
0131 if (IS_ERR_OR_NULL(sw))
0132 return;
0133
0134 for (i = 0; i < sw->num_sw_devs; i++) {
0135 sw_dev = sw->sw_devs[i];
0136
0137 module_put(sw_dev->dev.parent->driver->owner);
0138 put_device(&sw_dev->dev);
0139 }
0140 kfree(sw);
0141 }
0142 EXPORT_SYMBOL_GPL(typec_switch_put);
0143
0144 static void typec_switch_release(struct device *dev)
0145 {
0146 kfree(to_typec_switch_dev(dev));
0147 }
0148
0149 const struct device_type typec_switch_dev_type = {
0150 .name = "orientation_switch",
0151 .release = typec_switch_release,
0152 };
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164 struct typec_switch_dev *
0165 typec_switch_register(struct device *parent,
0166 const struct typec_switch_desc *desc)
0167 {
0168 struct typec_switch_dev *sw_dev;
0169 int ret;
0170
0171 if (!desc || !desc->set)
0172 return ERR_PTR(-EINVAL);
0173
0174 sw_dev = kzalloc(sizeof(*sw_dev), GFP_KERNEL);
0175 if (!sw_dev)
0176 return ERR_PTR(-ENOMEM);
0177
0178 sw_dev->set = desc->set;
0179
0180 device_initialize(&sw_dev->dev);
0181 sw_dev->dev.parent = parent;
0182 sw_dev->dev.fwnode = desc->fwnode;
0183 sw_dev->dev.class = &typec_mux_class;
0184 sw_dev->dev.type = &typec_switch_dev_type;
0185 sw_dev->dev.driver_data = desc->drvdata;
0186 ret = dev_set_name(&sw_dev->dev, "%s-switch", desc->name ? desc->name : dev_name(parent));
0187 if (ret) {
0188 put_device(&sw_dev->dev);
0189 return ERR_PTR(ret);
0190 }
0191
0192 ret = device_add(&sw_dev->dev);
0193 if (ret) {
0194 dev_err(parent, "failed to register switch (%d)\n", ret);
0195 put_device(&sw_dev->dev);
0196 return ERR_PTR(ret);
0197 }
0198
0199 return sw_dev;
0200 }
0201 EXPORT_SYMBOL_GPL(typec_switch_register);
0202
0203 int typec_switch_set(struct typec_switch *sw,
0204 enum typec_orientation orientation)
0205 {
0206 struct typec_switch_dev *sw_dev;
0207 unsigned int i;
0208 int ret;
0209
0210 if (IS_ERR_OR_NULL(sw))
0211 return 0;
0212
0213 for (i = 0; i < sw->num_sw_devs; i++) {
0214 sw_dev = sw->sw_devs[i];
0215
0216 ret = sw_dev->set(sw_dev, orientation);
0217 if (ret)
0218 return ret;
0219 }
0220
0221 return 0;
0222 }
0223 EXPORT_SYMBOL_GPL(typec_switch_set);
0224
0225
0226
0227
0228
0229
0230
0231 void typec_switch_unregister(struct typec_switch_dev *sw_dev)
0232 {
0233 if (!IS_ERR_OR_NULL(sw_dev))
0234 device_unregister(&sw_dev->dev);
0235 }
0236 EXPORT_SYMBOL_GPL(typec_switch_unregister);
0237
0238 void typec_switch_set_drvdata(struct typec_switch_dev *sw_dev, void *data)
0239 {
0240 dev_set_drvdata(&sw_dev->dev, data);
0241 }
0242 EXPORT_SYMBOL_GPL(typec_switch_set_drvdata);
0243
0244 void *typec_switch_get_drvdata(struct typec_switch_dev *sw_dev)
0245 {
0246 return dev_get_drvdata(&sw_dev->dev);
0247 }
0248 EXPORT_SYMBOL_GPL(typec_switch_get_drvdata);
0249
0250
0251
0252 struct typec_mux {
0253 struct typec_mux_dev *mux_devs[TYPEC_MUX_MAX_DEVS];
0254 unsigned int num_mux_devs;
0255 };
0256
0257 static int mux_fwnode_match(struct device *dev, const void *fwnode)
0258 {
0259 if (!is_typec_mux_dev(dev))
0260 return 0;
0261
0262 return dev_fwnode(dev) == fwnode;
0263 }
0264
0265 static void *typec_mux_match(struct fwnode_handle *fwnode, const char *id,
0266 void *data)
0267 {
0268 const struct typec_altmode_desc *desc = data;
0269 struct device *dev;
0270 bool match;
0271 int nval;
0272 u16 *val;
0273 int ret;
0274 int i;
0275
0276
0277
0278
0279
0280 match = !id;
0281 if (match)
0282 goto find_mux;
0283
0284 if (!desc) {
0285
0286
0287
0288
0289 match = fwnode_property_present(fwnode, "accessory") ||
0290 fwnode_property_present(fwnode, id);
0291 if (match)
0292 goto find_mux;
0293 return NULL;
0294 }
0295
0296
0297 nval = fwnode_property_count_u16(fwnode, "svid");
0298 if (nval <= 0)
0299 return NULL;
0300
0301 val = kcalloc(nval, sizeof(*val), GFP_KERNEL);
0302 if (!val)
0303 return ERR_PTR(-ENOMEM);
0304
0305 ret = fwnode_property_read_u16_array(fwnode, "svid", val, nval);
0306 if (ret < 0) {
0307 kfree(val);
0308 return ERR_PTR(ret);
0309 }
0310
0311 for (i = 0; i < nval; i++) {
0312 match = val[i] == desc->svid;
0313 if (match) {
0314 kfree(val);
0315 goto find_mux;
0316 }
0317 }
0318 kfree(val);
0319 return NULL;
0320
0321 find_mux:
0322 dev = class_find_device(&typec_mux_class, NULL, fwnode,
0323 mux_fwnode_match);
0324
0325 return dev ? to_typec_mux_dev(dev) : ERR_PTR(-EPROBE_DEFER);
0326 }
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338 struct typec_mux *fwnode_typec_mux_get(struct fwnode_handle *fwnode,
0339 const struct typec_altmode_desc *desc)
0340 {
0341 struct typec_mux_dev *mux_devs[TYPEC_MUX_MAX_DEVS];
0342 struct typec_mux *mux;
0343 int count;
0344 int err;
0345 int i;
0346
0347 mux = kzalloc(sizeof(*mux), GFP_KERNEL);
0348 if (!mux)
0349 return ERR_PTR(-ENOMEM);
0350
0351 count = fwnode_connection_find_matches(fwnode, "mode-switch",
0352 (void *)desc, typec_mux_match,
0353 (void **)mux_devs,
0354 ARRAY_SIZE(mux_devs));
0355 if (count <= 0) {
0356 kfree(mux);
0357 return NULL;
0358 }
0359
0360 for (i = 0; i < count; i++) {
0361 if (IS_ERR(mux_devs[i])) {
0362 err = PTR_ERR(mux_devs[i]);
0363 goto put_mux_devs;
0364 }
0365 }
0366
0367 for (i = 0; i < count; i++) {
0368 WARN_ON(!try_module_get(mux_devs[i]->dev.parent->driver->owner));
0369 mux->mux_devs[i] = mux_devs[i];
0370 }
0371
0372 mux->num_mux_devs = count;
0373
0374 return mux;
0375
0376 put_mux_devs:
0377 for (i = 0; i < count; i++) {
0378 if (!IS_ERR(mux_devs[i]))
0379 put_device(&mux_devs[i]->dev);
0380 }
0381
0382 kfree(mux);
0383
0384 return ERR_PTR(err);
0385 }
0386 EXPORT_SYMBOL_GPL(fwnode_typec_mux_get);
0387
0388
0389
0390
0391
0392
0393
0394 void typec_mux_put(struct typec_mux *mux)
0395 {
0396 struct typec_mux_dev *mux_dev;
0397 unsigned int i;
0398
0399 if (IS_ERR_OR_NULL(mux))
0400 return;
0401
0402 for (i = 0; i < mux->num_mux_devs; i++) {
0403 mux_dev = mux->mux_devs[i];
0404 module_put(mux_dev->dev.parent->driver->owner);
0405 put_device(&mux_dev->dev);
0406 }
0407 kfree(mux);
0408 }
0409 EXPORT_SYMBOL_GPL(typec_mux_put);
0410
0411 int typec_mux_set(struct typec_mux *mux, struct typec_mux_state *state)
0412 {
0413 struct typec_mux_dev *mux_dev;
0414 unsigned int i;
0415 int ret;
0416
0417 if (IS_ERR_OR_NULL(mux))
0418 return 0;
0419
0420 for (i = 0; i < mux->num_mux_devs; i++) {
0421 mux_dev = mux->mux_devs[i];
0422
0423 ret = mux_dev->set(mux_dev, state);
0424 if (ret)
0425 return ret;
0426 }
0427
0428 return 0;
0429 }
0430 EXPORT_SYMBOL_GPL(typec_mux_set);
0431
0432 static void typec_mux_release(struct device *dev)
0433 {
0434 kfree(to_typec_mux_dev(dev));
0435 }
0436
0437 const struct device_type typec_mux_dev_type = {
0438 .name = "mode_switch",
0439 .release = typec_mux_release,
0440 };
0441
0442
0443
0444
0445
0446
0447
0448
0449
0450
0451
0452 struct typec_mux_dev *
0453 typec_mux_register(struct device *parent, const struct typec_mux_desc *desc)
0454 {
0455 struct typec_mux_dev *mux_dev;
0456 int ret;
0457
0458 if (!desc || !desc->set)
0459 return ERR_PTR(-EINVAL);
0460
0461 mux_dev = kzalloc(sizeof(*mux_dev), GFP_KERNEL);
0462 if (!mux_dev)
0463 return ERR_PTR(-ENOMEM);
0464
0465 mux_dev->set = desc->set;
0466
0467 device_initialize(&mux_dev->dev);
0468 mux_dev->dev.parent = parent;
0469 mux_dev->dev.fwnode = desc->fwnode;
0470 mux_dev->dev.class = &typec_mux_class;
0471 mux_dev->dev.type = &typec_mux_dev_type;
0472 mux_dev->dev.driver_data = desc->drvdata;
0473 ret = dev_set_name(&mux_dev->dev, "%s-mux", desc->name ? desc->name : dev_name(parent));
0474 if (ret) {
0475 put_device(&mux_dev->dev);
0476 return ERR_PTR(ret);
0477 }
0478
0479 ret = device_add(&mux_dev->dev);
0480 if (ret) {
0481 dev_err(parent, "failed to register mux (%d)\n", ret);
0482 put_device(&mux_dev->dev);
0483 return ERR_PTR(ret);
0484 }
0485
0486 return mux_dev;
0487 }
0488 EXPORT_SYMBOL_GPL(typec_mux_register);
0489
0490
0491
0492
0493
0494
0495
0496 void typec_mux_unregister(struct typec_mux_dev *mux_dev)
0497 {
0498 if (!IS_ERR_OR_NULL(mux_dev))
0499 device_unregister(&mux_dev->dev);
0500 }
0501 EXPORT_SYMBOL_GPL(typec_mux_unregister);
0502
0503 void typec_mux_set_drvdata(struct typec_mux_dev *mux_dev, void *data)
0504 {
0505 dev_set_drvdata(&mux_dev->dev, data);
0506 }
0507 EXPORT_SYMBOL_GPL(typec_mux_set_drvdata);
0508
0509 void *typec_mux_get_drvdata(struct typec_mux_dev *mux_dev)
0510 {
0511 return dev_get_drvdata(&mux_dev->dev);
0512 }
0513 EXPORT_SYMBOL_GPL(typec_mux_get_drvdata);
0514
0515 struct class typec_mux_class = {
0516 .name = "typec_mux",
0517 .owner = THIS_MODULE,
0518 };