Lines Matching +full:spi +full:- +full:tx +full:- +full:bus +full:- +full:width
4 * SPDX-License-Identifier: GPL-2.0+
11 #include <spi.h>
12 #include <dm/device-internal.h>
13 #include <dm/uclass-internal.h>
21 static int spi_set_speed_mode(struct udevice *bus, int speed, int mode) in spi_set_speed_mode() argument
26 ops = spi_get_ops(bus); in spi_set_speed_mode()
27 if (ops->set_speed) in spi_set_speed_mode()
28 ret = ops->set_speed(bus, speed); in spi_set_speed_mode()
30 ret = -EINVAL; in spi_set_speed_mode()
36 if (ops->set_mode) in spi_set_speed_mode()
37 ret = ops->set_mode(bus, mode); in spi_set_speed_mode()
39 ret = -EINVAL; in spi_set_speed_mode()
50 struct udevice *bus = dev->parent; in dm_spi_claim_bus() local
51 struct dm_spi_ops *ops = spi_get_ops(bus); in dm_spi_claim_bus()
52 struct dm_spi_bus *spi = dev_get_uclass_priv(bus); in dm_spi_claim_bus() local
56 speed = slave->max_hz; in dm_spi_claim_bus()
57 mode = slave->mode; in dm_spi_claim_bus()
59 if (spi->max_hz) { in dm_spi_claim_bus()
61 speed = min(speed, spi->max_hz); in dm_spi_claim_bus()
63 speed = spi->max_hz; in dm_spi_claim_bus()
68 if (speed != spi->speed || mode != spi->mode) { in dm_spi_claim_bus()
69 int ret = spi_set_speed_mode(bus, speed, slave->mode); in dm_spi_claim_bus()
74 spi->speed = speed; in dm_spi_claim_bus()
75 spi->mode = mode; in dm_spi_claim_bus()
78 return log_ret(ops->claim_bus ? ops->claim_bus(dev) : 0); in dm_spi_claim_bus()
83 struct udevice *bus = dev->parent; in dm_spi_release_bus() local
84 struct dm_spi_ops *ops = spi_get_ops(bus); in dm_spi_release_bus()
86 if (ops->release_bus) in dm_spi_release_bus()
87 ops->release_bus(dev); in dm_spi_release_bus()
93 struct udevice *bus = dev->parent; in dm_spi_xfer() local
94 struct dm_spi_ops *ops = spi_get_ops(bus); in dm_spi_xfer()
96 if (bus->uclass->uc_drv->id != UCLASS_SPI) in dm_spi_xfer()
97 return -EOPNOTSUPP; in dm_spi_xfer()
98 if (!ops->xfer) in dm_spi_xfer()
99 return -ENOSYS; in dm_spi_xfer()
101 return ops->xfer(dev, bitlen, dout, din, flags); in dm_spi_xfer()
107 struct udevice *bus = dev->parent; in dm_spi_get_mmap() local
108 struct dm_spi_ops *ops = spi_get_ops(bus); in dm_spi_get_mmap()
110 if (bus->uclass->uc_drv->id != UCLASS_SPI) in dm_spi_get_mmap()
111 return -EOPNOTSUPP; in dm_spi_get_mmap()
112 if (!ops->get_mmap) in dm_spi_get_mmap()
113 return -ENOSYS; in dm_spi_get_mmap()
115 return ops->get_mmap(dev, map_basep, map_sizep, offsetp); in dm_spi_get_mmap()
120 return log_ret(dm_spi_claim_bus(slave->dev)); in spi_claim_bus()
125 dm_spi_release_bus(slave->dev); in spi_release_bus()
131 return dm_spi_xfer(slave->dev, bitlen, dout, din, flags); in spi_xfer()
146 debug("spi: failed to send command (%zu bytes): %d\n", in spi_write_then_read()
151 debug("spi: failed to transfer %zu bytes of data: %d\n", in spi_write_then_read()
170 static int spi_post_probe(struct udevice *bus) in spi_post_probe() argument
173 struct dm_spi_bus *spi = dev_get_uclass_priv(bus); in spi_post_probe() local
175 spi->max_hz = dev_read_u32_default(bus, "spi-max-frequency", 0); in spi_post_probe()
178 struct dm_spi_ops *ops = spi_get_ops(bus); in spi_post_probe()
182 if (ops->claim_bus) in spi_post_probe()
183 ops->claim_bus += gd->reloc_off; in spi_post_probe()
184 if (ops->release_bus) in spi_post_probe()
185 ops->release_bus += gd->reloc_off; in spi_post_probe()
186 if (ops->set_wordlen) in spi_post_probe()
187 ops->set_wordlen += gd->reloc_off; in spi_post_probe()
188 if (ops->xfer) in spi_post_probe()
189 ops->xfer += gd->reloc_off; in spi_post_probe()
190 if (ops->set_speed) in spi_post_probe()
191 ops->set_speed += gd->reloc_off; in spi_post_probe()
192 if (ops->set_mode) in spi_post_probe()
193 ops->set_mode += gd->reloc_off; in spi_post_probe()
194 if (ops->cs_info) in spi_post_probe()
195 ops->cs_info += gd->reloc_off; in spi_post_probe()
210 * instead slave->dev (a struct udevice). So we have to have some in spi_child_pre_probe()
212 * change the SPI API to use udevice instead of spi_slave, we can in spi_child_pre_probe()
215 slave->dev = dev; in spi_child_pre_probe()
217 slave->max_hz = plat->max_hz; in spi_child_pre_probe()
218 slave->mode = plat->mode; in spi_child_pre_probe()
219 slave->wordlen = SPI_DEFAULT_WORDLEN; in spi_child_pre_probe()
228 return plat ? plat->cs : -ENOENT; in spi_chip_select()
231 int spi_find_chip_select(struct udevice *bus, int cs, struct udevice **devp) in spi_find_chip_select() argument
244 ops = spi_get_ops(bus); in spi_find_chip_select()
245 if (ops->cs_info) { in spi_find_chip_select()
246 ret = ops->cs_info(bus, cs, &info); in spi_find_chip_select()
260 for (device_find_first_child(bus, &dev); dev; in spi_find_chip_select()
265 debug("%s: plat=%p, cs=%d\n", __func__, plat, plat->cs); in spi_find_chip_select()
266 if (plat->cs == cs) { in spi_find_chip_select()
272 return -ENODEV; in spi_find_chip_select()
278 struct udevice *bus; in spi_cs_is_valid() local
281 ret = uclass_find_device_by_seq(UCLASS_SPI, busnum, false, &bus); in spi_cs_is_valid()
283 debug("%s: No bus %d\n", __func__, busnum); in spi_cs_is_valid()
287 return spi_cs_info(bus, cs, &info); in spi_cs_is_valid()
290 int spi_cs_info(struct udevice *bus, uint cs, struct spi_cs_info *info) in spi_cs_info() argument
299 info->dev = NULL; in spi_cs_info()
300 ret = spi_find_chip_select(bus, cs, &info->dev); in spi_cs_info()
301 return ret == -ENODEV ? 0 : ret; in spi_cs_info()
307 struct udevice *bus, *dev; in spi_find_bus_and_cs() local
310 ret = uclass_find_device_by_seq(UCLASS_SPI, busnum, false, &bus); in spi_find_bus_and_cs()
312 debug("%s: No bus %d\n", __func__, busnum); in spi_find_bus_and_cs()
315 ret = spi_find_chip_select(bus, cs, &dev); in spi_find_bus_and_cs()
320 *busp = bus; in spi_find_bus_and_cs()
330 struct udevice *bus, *dev; in spi_get_bus_and_cs() local
338 ret = uclass_first_device_err(UCLASS_SPI, &bus); in spi_get_bus_and_cs()
340 ret = uclass_get_device_by_seq(UCLASS_SPI, busnum, &bus); in spi_get_bus_and_cs()
343 printf("Invalid bus %d (err=%d)\n", busnum, ret); in spi_get_bus_and_cs()
346 ret = spi_find_chip_select(bus, cs, &dev); in spi_get_bus_and_cs()
351 * SPI flash chip - we will bind to the correct driver. in spi_get_bus_and_cs()
353 if (ret == -ENODEV && drv_name) { in spi_get_bus_and_cs()
356 ret = device_bind_driver(bus, drv_name, dev_name, &dev); in spi_get_bus_and_cs()
363 plat->cs = cs; in spi_get_bus_and_cs()
365 plat->max_hz = speed; in spi_get_bus_and_cs()
367 printf("Warning: SPI speed fallback to %u kHz\n", in spi_get_bus_and_cs()
369 plat->max_hz = SPI_DEFAULT_SPEED_HZ; in spi_get_bus_and_cs()
371 plat->mode = mode; in spi_get_bus_and_cs()
386 slave->dev = dev; in spi_get_bus_and_cs()
390 bus_data = dev_get_uclass_priv(bus); in spi_get_bus_and_cs()
394 * dm_spi_claim_bus() ensure the bus is configured properly. in spi_get_bus_and_cs()
396 if (!bus_data->speed) { in spi_get_bus_and_cs()
402 *busp = bus; in spi_get_bus_and_cs()
404 debug("%s: bus=%p, slave=%p\n", __func__, bus, *devp); in spi_get_bus_and_cs()
410 created, dev->name); in spi_get_bus_and_cs()
419 /* Compatibility function - to be removed */
437 device_remove(slave->dev, DM_REMOVE_NORMAL); in spi_free_slave()
438 slave->dev = NULL; in spi_free_slave()
447 plat->cs = dev_read_u32_default(dev, "reg", -1); in spi_slave_ofdata_to_platdata()
448 plat->max_hz = dev_read_u32_default(dev, "spi-max-frequency", in spi_slave_ofdata_to_platdata()
450 if (dev_read_bool(dev, "spi-cpol")) in spi_slave_ofdata_to_platdata()
452 if (dev_read_bool(dev, "spi-cpha")) in spi_slave_ofdata_to_platdata()
454 if (dev_read_bool(dev, "spi-cs-high")) in spi_slave_ofdata_to_platdata()
456 if (dev_read_bool(dev, "spi-3wire")) in spi_slave_ofdata_to_platdata()
458 if (dev_read_bool(dev, "spi-half-duplex")) in spi_slave_ofdata_to_platdata()
462 value = dev_read_u32_default(dev, "spi-tx-bus-width", 1); in spi_slave_ofdata_to_platdata()
476 warn_non_spl("spi-tx-bus-width %d not supported\n", value); in spi_slave_ofdata_to_platdata()
480 value = dev_read_u32_default(dev, "spi-rx-bus-width", 1); in spi_slave_ofdata_to_platdata()
494 warn_non_spl("spi-rx-bus-width %d not supported\n", value); in spi_slave_ofdata_to_platdata()
498 plat->mode = mode; in spi_slave_ofdata_to_platdata()
503 UCLASS_DRIVER(spi) = {
505 .name = "spi",