+
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
+ const void *dout, void *din, unsigned long flags)
+{
+ struct omap3_spi_priv *priv = to_omap3_spi(slave);
+
+ return _spi_xfer(priv, bitlen, dout, din, flags);
+}
+
+#else
+
+static int omap3_spi_claim_bus(struct udevice *dev)
+{
+ struct udevice *bus = dev->parent;
+ struct omap3_spi_priv *priv = dev_get_priv(bus);
+ struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
+
+ priv->cs = slave_plat->cs;
+ priv->mode = slave_plat->mode;
+ priv->freq = slave_plat->max_hz;
+ _omap3_spi_claim_bus(priv);
+
+ return 0;
+}
+
+static int omap3_spi_release_bus(struct udevice *dev)
+{
+ struct udevice *bus = dev->parent;
+ struct omap3_spi_priv *priv = dev_get_priv(bus);
+
+ /* Reset the SPI hardware */
+ spi_reset(priv->regs);
+
+ return 0;
+}
+
+static int omap3_spi_set_wordlen(struct udevice *dev, unsigned int wordlen)
+{
+ struct udevice *bus = dev->parent;
+ struct omap3_spi_priv *priv = dev_get_priv(bus);
+ struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
+
+ priv->cs = slave_plat->cs;
+ priv->wordlen = wordlen;
+ _omap3_spi_set_wordlen(priv);
+
+ return 0;
+}
+
+static int omap3_spi_probe(struct udevice *dev)
+{
+ struct omap3_spi_priv *priv = dev_get_priv(dev);
+ const void *blob = gd->fdt_blob;
+ int node = dev->of_offset;
+
+ struct omap2_mcspi_platform_config* data =
+ (struct omap2_mcspi_platform_config*)dev_get_driver_data(dev);
+
+ priv->regs = (struct mcspi *)(dev_get_addr(dev) + data->regs_offset);
+ priv->pin_dir = fdtdec_get_uint(blob, node, "ti,pindir-d0-out-d1-in",
+ MCSPI_PINDIR_D0_IN_D1_OUT);
+ priv->wordlen = SPI_DEFAULT_WORDLEN;
+ return 0;
+}
+
+static int omap3_spi_xfer(struct udevice *dev, unsigned int bitlen,
+ const void *dout, void *din, unsigned long flags)
+{
+ struct udevice *bus = dev->parent;
+ struct omap3_spi_priv *priv = dev_get_priv(bus);
+
+ return _spi_xfer(priv, bitlen, dout, din, flags);
+}
+
+static int omap3_spi_set_speed(struct udevice *bus, unsigned int speed)
+{
+ return 0;
+}
+
+static int omap3_spi_set_mode(struct udevice *bus, uint mode)
+{
+ return 0;
+}
+
+static const struct dm_spi_ops omap3_spi_ops = {
+ .claim_bus = omap3_spi_claim_bus,
+ .release_bus = omap3_spi_release_bus,
+ .set_wordlen = omap3_spi_set_wordlen,
+ .xfer = omap3_spi_xfer,
+ .set_speed = omap3_spi_set_speed,
+ .set_mode = omap3_spi_set_mode,
+ /*
+ * cs_info is not needed, since we require all chip selects to be
+ * in the device tree explicitly
+ */
+};
+
+static struct omap2_mcspi_platform_config omap2_pdata = {
+ .regs_offset = 0,
+};
+
+static struct omap2_mcspi_platform_config omap4_pdata = {
+ .regs_offset = OMAP4_MCSPI_REG_OFFSET,
+};
+
+static const struct udevice_id omap3_spi_ids[] = {
+ { .compatible = "ti,omap2-mcspi", .data = (ulong)&omap2_pdata },
+ { .compatible = "ti,omap4-mcspi", .data = (ulong)&omap4_pdata },
+ { }
+};
+
+U_BOOT_DRIVER(omap3_spi) = {
+ .name = "omap3_spi",
+ .id = UCLASS_SPI,
+ .of_match = omap3_spi_ids,
+ .probe = omap3_spi_probe,
+ .ops = &omap3_spi_ops,
+ .priv_auto_alloc_size = sizeof(struct omap3_spi_priv),
+ .probe = omap3_spi_probe,
+};
+#endif