14395e06eSThomas Chou /* 24395e06eSThomas Chou * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw> 34395e06eSThomas Chou * 44395e06eSThomas Chou * SPDX-License-Identifier: GPL-2.0+ 54395e06eSThomas Chou */ 64395e06eSThomas Chou 74395e06eSThomas Chou #include <common.h> 84395e06eSThomas Chou #include <dm.h> 94395e06eSThomas Chou #include <errno.h> 104395e06eSThomas Chou #include <misc.h> 114395e06eSThomas Chou 124395e06eSThomas Chou /* 134395e06eSThomas Chou * Implement a miscellaneous uclass for those do not fit other more 144395e06eSThomas Chou * general classes. A set of generic read, write and ioctl methods may 154395e06eSThomas Chou * be used to access the device. 164395e06eSThomas Chou */ 174395e06eSThomas Chou 184395e06eSThomas Chou int misc_read(struct udevice *dev, int offset, void *buf, int size) 194395e06eSThomas Chou { 204395e06eSThomas Chou const struct misc_ops *ops = device_get_ops(dev); 214395e06eSThomas Chou 224395e06eSThomas Chou if (!ops->read) 234395e06eSThomas Chou return -ENOSYS; 244395e06eSThomas Chou 254395e06eSThomas Chou return ops->read(dev, offset, buf, size); 264395e06eSThomas Chou } 274395e06eSThomas Chou 284395e06eSThomas Chou int misc_write(struct udevice *dev, int offset, void *buf, int size) 294395e06eSThomas Chou { 304395e06eSThomas Chou const struct misc_ops *ops = device_get_ops(dev); 314395e06eSThomas Chou 324395e06eSThomas Chou if (!ops->write) 334395e06eSThomas Chou return -ENOSYS; 344395e06eSThomas Chou 354395e06eSThomas Chou return ops->write(dev, offset, buf, size); 364395e06eSThomas Chou } 374395e06eSThomas Chou 384395e06eSThomas Chou int misc_ioctl(struct udevice *dev, unsigned long request, void *buf) 394395e06eSThomas Chou { 404395e06eSThomas Chou const struct misc_ops *ops = device_get_ops(dev); 414395e06eSThomas Chou 424395e06eSThomas Chou if (!ops->ioctl) 434395e06eSThomas Chou return -ENOSYS; 444395e06eSThomas Chou 454395e06eSThomas Chou return ops->ioctl(dev, request, buf); 464395e06eSThomas Chou } 474395e06eSThomas Chou 48b647f554SStephen Warren int misc_call(struct udevice *dev, int msgid, void *tx_msg, int tx_size, 49b647f554SStephen Warren void *rx_msg, int rx_size) 50b647f554SStephen Warren { 51b647f554SStephen Warren const struct misc_ops *ops = device_get_ops(dev); 52b647f554SStephen Warren 53b647f554SStephen Warren if (!ops->call) 54b647f554SStephen Warren return -ENOSYS; 55b647f554SStephen Warren 56b647f554SStephen Warren return ops->call(dev, msgid, tx_msg, tx_size, rx_msg, rx_size); 57b647f554SStephen Warren } 58b647f554SStephen Warren 59*374c241cSJoseph Chen struct udevice *misc_get_device_by_capability(u32 capability) 60*374c241cSJoseph Chen { 61*374c241cSJoseph Chen const struct misc_ops *ops; 62*374c241cSJoseph Chen struct udevice *dev; 63*374c241cSJoseph Chen struct uclass *uc; 64*374c241cSJoseph Chen int ret; 65*374c241cSJoseph Chen u32 cap; 66*374c241cSJoseph Chen 67*374c241cSJoseph Chen ret = uclass_get(UCLASS_MISC, &uc); 68*374c241cSJoseph Chen if (ret) 69*374c241cSJoseph Chen return NULL; 70*374c241cSJoseph Chen 71*374c241cSJoseph Chen for (uclass_first_device(UCLASS_MISC, &dev); 72*374c241cSJoseph Chen dev; 73*374c241cSJoseph Chen uclass_next_device(&dev)) { 74*374c241cSJoseph Chen ops = device_get_ops(dev); 75*374c241cSJoseph Chen if (!ops || !ops->ioctl) 76*374c241cSJoseph Chen continue; 77*374c241cSJoseph Chen 78*374c241cSJoseph Chen ret = ops->ioctl(dev, IOCTL_REQ_CAPABILITY, &cap); 79*374c241cSJoseph Chen if (!ret && ((cap & capability) == capability)) 80*374c241cSJoseph Chen return dev; 81*374c241cSJoseph Chen } 82*374c241cSJoseph Chen 83*374c241cSJoseph Chen return NULL; 84*374c241cSJoseph Chen } 85*374c241cSJoseph Chen 864395e06eSThomas Chou UCLASS_DRIVER(misc) = { 874395e06eSThomas Chou .id = UCLASS_MISC, 884395e06eSThomas Chou .name = "misc", 894395e06eSThomas Chou }; 90