1 /* 2 * SD card bus interface code. 3 * 4 * Copyright (c) 2015 Linaro Limited 5 * 6 * Author: 7 * Peter Maydell <peter.maydell@linaro.org> 8 * 9 * This program is free software; you can redistribute it and/or modify it 10 * under the terms and conditions of the GNU General Public License, 11 * version 2 or later, as published by the Free Software Foundation. 12 * 13 * This program is distributed in the hope it will be useful, but WITHOUT 14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 16 * more details. 17 * 18 * You should have received a copy of the GNU General Public License along with 19 * this program. If not, see <http://www.gnu.org/licenses/>. 20 */ 21 22 #include "qemu/osdep.h" 23 #include "hw/qdev-core.h" 24 #include "hw/sd/sd.h" 25 #include "qemu/module.h" 26 #include "qapi/error.h" 27 #include "sdmmc-internal.h" 28 #include "trace.h" 29 30 static inline const char *sdbus_name(SDBus *sdbus) 31 { 32 return sdbus->qbus.name; 33 } 34 35 static SDState *get_card(SDBus *sdbus) 36 { 37 /* We only ever have one child on the bus so just return it */ 38 BusChild *kid = QTAILQ_FIRST(&sdbus->qbus.children); 39 40 if (!kid) { 41 return NULL; 42 } 43 return SDMMC_COMMON(kid->child); 44 } 45 46 uint8_t sdbus_get_dat_lines(SDBus *sdbus) 47 { 48 SDState *slave = get_card(sdbus); 49 uint8_t dat_lines = 0b1111; /* 4 bit bus width */ 50 51 if (slave) { 52 SDCardClass *sc = SDMMC_COMMON_GET_CLASS(slave); 53 54 if (sc->get_dat_lines) { 55 dat_lines = sc->get_dat_lines(slave); 56 } 57 } 58 trace_sdbus_get_dat_lines(sdbus_name(sdbus), dat_lines); 59 60 return dat_lines; 61 } 62 63 bool sdbus_get_cmd_line(SDBus *sdbus) 64 { 65 SDState *slave = get_card(sdbus); 66 bool cmd_line = true; 67 68 if (slave) { 69 SDCardClass *sc = SDMMC_COMMON_GET_CLASS(slave); 70 71 if (sc->get_cmd_line) { 72 cmd_line = sc->get_cmd_line(slave); 73 } 74 } 75 trace_sdbus_get_cmd_line(sdbus_name(sdbus), cmd_line); 76 77 return cmd_line; 78 } 79 80 void sdbus_set_voltage(SDBus *sdbus, uint16_t millivolts) 81 { 82 SDState *card = get_card(sdbus); 83 84 trace_sdbus_set_voltage(sdbus_name(sdbus), millivolts); 85 if (card) { 86 SDCardClass *sc = SDMMC_COMMON_GET_CLASS(card); 87 88 assert(sc->set_voltage); 89 sc->set_voltage(card, millivolts); 90 } 91 } 92 93 int sdbus_do_command(SDBus *sdbus, SDRequest *req, uint8_t *response) 94 { 95 SDState *card = get_card(sdbus); 96 97 trace_sdbus_command(sdbus_name(sdbus), req->cmd, req->arg); 98 if (card) { 99 SDCardClass *sc = SDMMC_COMMON_GET_CLASS(card); 100 101 return sc->do_command(card, req, response); 102 } 103 104 return 0; 105 } 106 107 void sdbus_write_byte(SDBus *sdbus, uint8_t value) 108 { 109 SDState *card = get_card(sdbus); 110 111 trace_sdbus_write(sdbus_name(sdbus), value); 112 if (card) { 113 SDCardClass *sc = SDMMC_COMMON_GET_CLASS(card); 114 115 sc->write_byte(card, value); 116 } 117 } 118 119 void sdbus_write_data(SDBus *sdbus, const void *buf, size_t length) 120 { 121 SDState *card = get_card(sdbus); 122 const uint8_t *data = buf; 123 124 if (card) { 125 SDCardClass *sc = SDMMC_COMMON_GET_CLASS(card); 126 127 for (size_t i = 0; i < length; i++) { 128 trace_sdbus_write(sdbus_name(sdbus), data[i]); 129 sc->write_byte(card, data[i]); 130 } 131 } 132 } 133 134 uint8_t sdbus_read_byte(SDBus *sdbus) 135 { 136 SDState *card = get_card(sdbus); 137 uint8_t value = 0; 138 139 if (card) { 140 SDCardClass *sc = SDMMC_COMMON_GET_CLASS(card); 141 142 value = sc->read_byte(card); 143 } 144 trace_sdbus_read(sdbus_name(sdbus), value); 145 146 return value; 147 } 148 149 void sdbus_read_data(SDBus *sdbus, void *buf, size_t length) 150 { 151 SDState *card = get_card(sdbus); 152 uint8_t *data = buf; 153 154 if (card) { 155 SDCardClass *sc = SDMMC_COMMON_GET_CLASS(card); 156 157 for (size_t i = 0; i < length; i++) { 158 data[i] = sc->read_byte(card); 159 trace_sdbus_read(sdbus_name(sdbus), data[i]); 160 } 161 } 162 } 163 164 bool sdbus_receive_ready(SDBus *sdbus) 165 { 166 SDState *card = get_card(sdbus); 167 168 if (card) { 169 SDCardClass *sc = SDMMC_COMMON_GET_CLASS(card); 170 171 return sc->receive_ready(card); 172 } 173 174 return false; 175 } 176 177 bool sdbus_data_ready(SDBus *sdbus) 178 { 179 SDState *card = get_card(sdbus); 180 181 if (card) { 182 SDCardClass *sc = SDMMC_COMMON_GET_CLASS(card); 183 184 return sc->data_ready(card); 185 } 186 187 return false; 188 } 189 190 bool sdbus_get_inserted(SDBus *sdbus) 191 { 192 SDState *card = get_card(sdbus); 193 194 if (card) { 195 SDCardClass *sc = SDMMC_COMMON_GET_CLASS(card); 196 197 return sc->get_inserted(card); 198 } 199 200 return false; 201 } 202 203 bool sdbus_get_readonly(SDBus *sdbus) 204 { 205 SDState *card = get_card(sdbus); 206 207 if (card) { 208 SDCardClass *sc = SDMMC_COMMON_GET_CLASS(card); 209 210 return sc->get_readonly(card); 211 } 212 213 return false; 214 } 215 216 void sdbus_set_inserted(SDBus *sdbus, bool inserted) 217 { 218 SDBusClass *sbc = SD_BUS_GET_CLASS(sdbus); 219 BusState *qbus = BUS(sdbus); 220 221 if (sbc->set_inserted) { 222 sbc->set_inserted(qbus->parent, inserted); 223 } 224 } 225 226 void sdbus_set_readonly(SDBus *sdbus, bool readonly) 227 { 228 SDBusClass *sbc = SD_BUS_GET_CLASS(sdbus); 229 BusState *qbus = BUS(sdbus); 230 231 if (sbc->set_readonly) { 232 sbc->set_readonly(qbus->parent, readonly); 233 } 234 } 235 236 void sdbus_reparent_card(SDBus *from, SDBus *to) 237 { 238 SDState *card = get_card(from); 239 SDCardClass *sc; 240 bool readonly; 241 242 /* We directly reparent the card object rather than implementing this 243 * as a hotpluggable connection because we don't want to expose SD cards 244 * to users as being hotpluggable, and we can get away with it in this 245 * limited use case. This could perhaps be implemented more cleanly in 246 * future by adding support to the hotplug infrastructure for "device 247 * can be hotplugged only via code, not by user". 248 */ 249 250 if (!card) { 251 return; 252 } 253 254 sc = SDMMC_COMMON_GET_CLASS(card); 255 readonly = sc->get_readonly(card); 256 257 sdbus_set_inserted(from, false); 258 qdev_set_parent_bus(DEVICE(card), &to->qbus, &error_abort); 259 sdbus_set_inserted(to, true); 260 sdbus_set_readonly(to, readonly); 261 } 262 263 static const TypeInfo sd_bus_types[] = { 264 { 265 .name = TYPE_SD_BUS, 266 .parent = TYPE_BUS, 267 .instance_size = sizeof(SDBus), 268 .class_size = sizeof(SDBusClass), 269 }, 270 }; 271 272 DEFINE_TYPES(sd_bus_types) 273