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
misc_read(struct udevice * dev,int offset,void * buf,int size)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
misc_write(struct udevice * dev,int offset,void * buf,int size)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
misc_ioctl(struct udevice * dev,unsigned long request,void * buf)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
misc_call(struct udevice * dev,int msgid,void * tx_msg,int tx_size,void * rx_msg,int rx_size)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
misc_get_device_by_capability(u32 capability)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