1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2018 4 * Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc 5 */ 6 7 #include <common.h> 8 #include <dm.h> 9 #include <misc.h> 10 11 struct misc_sandbox_priv { 12 u8 mem[128]; 13 ulong last_ioctl; 14 bool enabled; 15 }; 16 17 int misc_sandbox_read(struct udevice *dev, int offset, void *buf, int size) 18 { 19 struct misc_sandbox_priv *priv = dev_get_priv(dev); 20 21 memcpy(buf, priv->mem + offset, size); 22 23 return 0; 24 } 25 26 int misc_sandbox_write(struct udevice *dev, int offset, const void *buf, 27 int size) 28 { 29 struct misc_sandbox_priv *priv = dev_get_priv(dev); 30 31 memcpy(priv->mem + offset, buf, size); 32 33 return 0; 34 } 35 36 int misc_sandbox_ioctl(struct udevice *dev, unsigned long request, void *buf) 37 { 38 struct misc_sandbox_priv *priv = dev_get_priv(dev); 39 40 priv->last_ioctl = request; 41 42 return 0; 43 } 44 45 int misc_sandbox_call(struct udevice *dev, int msgid, void *tx_msg, 46 int tx_size, void *rx_msg, int rx_size) 47 { 48 struct misc_sandbox_priv *priv = dev_get_priv(dev); 49 50 if (msgid == 0) { 51 int num = *(int *)tx_msg; 52 53 switch (num) { 54 case 0: 55 strncpy(rx_msg, "Zero", rx_size); 56 break; 57 case 1: 58 strncpy(rx_msg, "One", rx_size); 59 break; 60 case 2: 61 strncpy(rx_msg, "Two", rx_size); 62 break; 63 default: 64 return -EINVAL; 65 } 66 } 67 68 if (msgid == 1) { 69 int num = *(int *)tx_msg; 70 71 switch (num) { 72 case 0: 73 strncpy(rx_msg, "Forty", rx_size); 74 break; 75 case 1: 76 strncpy(rx_msg, "Forty-one", rx_size); 77 break; 78 case 2: 79 strncpy(rx_msg, "Forty-two", rx_size); 80 break; 81 default: 82 return -EINVAL; 83 } 84 } 85 86 if (msgid == 2) 87 memcpy(rx_msg, &priv->last_ioctl, sizeof(priv->last_ioctl)); 88 89 if (msgid == 3) 90 memcpy(rx_msg, &priv->enabled, sizeof(priv->enabled)); 91 92 return 0; 93 } 94 95 int misc_sandbox_set_enabled(struct udevice *dev, bool val) 96 { 97 struct misc_sandbox_priv *priv = dev_get_priv(dev); 98 99 priv->enabled = !priv->enabled; 100 101 return 0; 102 } 103 104 static const struct misc_ops misc_sandbox_ops = { 105 .read = misc_sandbox_read, 106 .write = misc_sandbox_write, 107 .ioctl = misc_sandbox_ioctl, 108 .call = misc_sandbox_call, 109 .set_enabled = misc_sandbox_set_enabled, 110 }; 111 112 int misc_sandbox_probe(struct udevice *dev) 113 { 114 struct misc_sandbox_priv *priv = dev_get_priv(dev); 115 116 priv->enabled = true; 117 118 return 0; 119 } 120 121 static const struct udevice_id misc_sandbox_ids[] = { 122 { .compatible = "sandbox,misc_sandbox" }, 123 { } 124 }; 125 126 U_BOOT_DRIVER(misc_sandbox) = { 127 .name = "misc_sandbox", 128 .id = UCLASS_MISC, 129 .ops = &misc_sandbox_ops, 130 .of_match = misc_sandbox_ids, 131 .probe = misc_sandbox_probe, 132 .priv_auto_alloc_size = sizeof(struct misc_sandbox_priv), 133 }; 134