All of lore.kernel.org
 help / color / mirror / Atom feed
From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 06/25] dm: spi: Add a uclass for SPI
Date: Mon, 11 Aug 2014 23:46:06 +0200	[thread overview]
Message-ID: <53E9399E.6000101@gmail.com> (raw)
In-Reply-To: <1405385792-4469-7-git-send-email-sjg@chromium.org>

Hi Simon,

some nitpicking

On 15.07.2014 02:56, Simon Glass wrote:
> Add a uclass which provides access to SPI buses and includes operations
> required by SPI.
> 
> For a time driver model will need to co-exist with the legacy SPI interface
> so some parts of the header file are changed depending on which is in use.
> The exports are adjusted also since some functions are not available with
> driver model.
> 
> Boards must define CONFIG_DM_SPI to use driver model for SPI.
> 
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
> 
>  common/exports.c         |   4 +-
>  drivers/spi/Makefile     |   4 +
>  drivers/spi/spi-uclass.c | 253 +++++++++++++++++++++++++++++++++++++++++++++++
>  include/dm/uclass-id.h   |   1 +
>  include/spi.h            | 140 ++++++++++++++++++++++++++
>  5 files changed, 401 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/spi/spi-uclass.c

...

> --- /dev/null
> +++ b/drivers/spi/spi-uclass.c
> @@ -0,0 +1,253 @@
> +/*
> + * Copyright (c) 2014 Google, Inc
> + *
> + * SPDX-License-Identifier:	GPL-2.0+
> + */
> +
> +#include <common.h>
> +#include <dm.h>
> +#include <errno.h>
> +#include <fdtdec.h>
> +#include <spi.h>
> +#include <dm/device-internal.h>
> +#include <dm/uclass-internal.h>
> +#include <dm/root.h>
> +#include <dm/lists.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +static int spi_set_speed_mode(struct udevice *bus, int speed, int mode)
> +{
> +	struct dm_spi_ops *ops;
> +	int ret;
> +
> +	ops = spi_get_ops(bus);
> +	if (ops->set_speed)
> +		ret = (*ops->set_speed)(bus, speed);

ret = ops->set_speed(bus, speed);

> +	else
> +		ret = -EINVAL;
> +	if (ret) {
> +		printf("Cannot set speed (err=%d)\n", ret);
> +		return ret;
> +	}
> +
> +	ops = spi_get_ops(bus);

redundant assignment

> +	if (ops->set_mode)
> +		ret = (*ops->set_mode)(bus, mode);

ret = ops->set_mode(bus, mode);

> +	else
> +		ret = -EINVAL;
> +	if (ret) {
> +		printf("Cannot set mode (err=%d)\n", ret);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +int spi_claim_bus(struct spi_slave *slave)
> +{
> +	struct udevice *dev = slave->dev;
> +	struct udevice *bus = dev->parent;
> +	struct dm_spi_ops *ops = spi_get_ops(bus);
> +	struct dm_spi_bus *spi = bus->uclass_priv;
> +	int speed;
> +	int ret;
> +
> +	speed = slave->max_hz;
> +	if (spi->max_hz) {
> +		if (speed)
> +			speed = min(speed, spi->max_hz);
> +		else
> +			speed = spi->max_hz;
> +	}
> +	if (!speed)
> +		speed = 100000;
> +	ret = spi_set_speed_mode(bus, speed, slave->mode);
> +	if (ret)
> +		return ret;
> +
> +	return ops->claim_bus ? ops->claim_bus(bus) : 0;
> +}
> +
> +void spi_release_bus(struct spi_slave *slave)
> +{
> +	struct udevice *dev = slave->dev;
> +	struct udevice *bus = dev->parent;
> +	struct dm_spi_ops *ops = spi_get_ops(bus);
> +
> +	if (ops->release_bus)
> +		spi_get_ops(bus)->release_bus(bus);

ops->release_bus(bus);

> +}
> +
> +int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
> +	     const void *dout, void *din, unsigned long flags)
> +{
> +	struct udevice *dev = slave->dev;
> +	struct udevice *bus = dev->parent;
> +
> +	if (bus->uclass->uc_drv->id != UCLASS_SPI)
> +		return -EOPNOTSUPP;
> +
> +	return spi_get_ops(bus)->xfer(bus, dev, bitlen, dout, din, flags);
> +}
> +
> +int spi_post_bind(struct udevice *dev)
> +{
> +	/* Scan the bus for devices */
> +	return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
> +}
> +
> +int spi_post_probe(struct udevice *dev)
> +{
> +	struct dm_spi_bus *spi = dev->uclass_priv;
> +
> +	spi->max_hz = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
> +				     "spi-max-frequency", 0);
> +
> +	return 0;
> +}
> +
> +int spi_bind_device(struct udevice *bus, int cs, const char *drv_name,
> +		    const char *dev_name, struct udevice **slavep)
> +{
> +	struct driver *drv;
> +	int ret;
> +
> +	drv = lists_driver_lookup_name(drv_name);
> +	if (!drv) {
> +		puts("Cannot find spi_flash_std driver\n");
> +		return -ENOENT;
> +	}
> +	ret = device_bind(bus, drv, dev_name, NULL, -1, slavep);
> +	if (ret) {
> +		printf("Cannot create device named '%s' (err=%d)\n",
> +		       dev_name, ret);
> +		return ret;
> +	}
> +	(*slavep)->req_seq = cs;
> +
> +	return 0;
> +}
> +
> +int spi_find_bus_and_cs(int busnum, int cs, struct udevice **busp,
> +			struct udevice **devp)
> +{
> +	struct udevice *bus, *dev;
> +	int ret;
> +
> +	ret = uclass_find_device_by_seq(UCLASS_SPI, busnum, false, &bus);
> +	if (ret)
> +		return ret;
> +	ret = device_find_child_by_seq(bus, cs, false, &dev);
> +	if (ret)
> +		return ret;
> +	*busp = bus;
> +	*devp = dev;
> +
> +	return ret;
> +}
> +
> +int spi_get_bus_and_cs(int busnum, int cs, int speed, int mode,
> +		       const char *drv_name, const char *dev_name,
> +		       struct udevice **devp, struct spi_slave **slavep)
> +{
> +	struct udevice *bus, *dev;
> +	int ret;
> +
> +	ret = uclass_get_device_by_seq(UCLASS_SPI, busnum, &bus);
> +	if (ret) {
> +		printf("Invalid bus %d (err=%d)\n", busnum, ret);
> +		return ret;
> +	}
> +	ret = device_get_child_by_seq(bus, cs, &dev);
> +
> +	/**
> +	 * If there is no such device, create one automatically. This means
> +	 * that we don't need a device tree node or platform data for the
> +	 * SPI flash chip - we will bind to the correct driver.
> +	 */
> +	if (ret == -ENODEV && drv_name) {
> +		ret = spi_bind_device(bus, cs, drv_name, dev_name, &dev);
> +		if (ret)
> +			return ret;
> +	}
> +	if (ret) {
> +		printf("Invalid chip select %d:%d (err=%d)\n", busnum, cs,
> +		       ret);
> +		return ret;
> +	}
> +
> +	ret = spi_set_speed_mode(bus, speed, mode);
> +	if (ret)
> +		return ret;
> +
> +	*devp = bus;
> +	*slavep = dev_get_parentdata(dev);
> +
> +	return 0;
> +}
> +
> +/* Compatibility function - to be removed */
> +struct spi_slave *spi_setup_slave_fdt(const void *blob, int node,
> +				      int bus_node)
> +{
> +	struct udevice *bus, *dev;
> +	int ret;
> +
> +	ret = uclass_get_device_by_of_offset(UCLASS_SPI, bus_node, &bus);
> +	if (ret)
> +		return NULL;
> +	ret = device_get_child_by_of_offset(bus, node, &dev);
> +	if (ret)
> +		return NULL;
> +	return dev_get_parentdata(dev);
> +}
> +
> +/* Compatibility function - to be removed */
> +struct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs,
> +				  unsigned int speed, unsigned int mode)
> +{
> +	struct spi_slave *slave;
> +	struct udevice *dev;
> +	int ret;
> +
> +	ret = spi_get_bus_and_cs(busnum, cs, speed, mode, NULL, 0, &dev,
> +				  &slave);
> +	if (ret)
> +		return NULL;
> +
> +	return slave;
> +}
> +
> +void spi_free_slave(struct spi_slave *slave)
> +{
> +	device_remove(slave->dev);
> +	slave->dev = NULL;
> +}
> +
> +int spi_ofdata_to_platdata(const void *blob, int node,
> +			   struct spi_slave *spi)
> +{
> +	int mode = 0;
> +
> +	spi->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", 0);
> +	if (fdtdec_get_bool(blob, node, "spi-cpol"))
> +		mode |= SPI_CPOL;
> +	if (fdtdec_get_bool(blob, node, "spi-cpha"))
> +		mode |= SPI_CPHA;
> +	if (fdtdec_get_bool(blob, node, "spi-cs-high"))
> +		mode |= SPI_CS_HIGH;
> +	if (fdtdec_get_bool(blob, node, "spi-half-duplex"))
> +		mode |= SPI_PREAMBLE;
> +	spi->mode = mode;
> +
> +	return 0;
> +}
> +
> +UCLASS_DRIVER(spi) = {
> +	.id		= UCLASS_SPI,
> +	.name		= "spi",
> +	.post_bind	= spi_post_bind,
> +	.post_probe	= spi_post_probe,
> +	.per_device_auto_alloc_size = sizeof(struct dm_spi_bus),
> +};


-- 
- Daniel

  parent reply	other threads:[~2014-08-11 21:46 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-15  0:56 [U-Boot] [PATCH 0/25] Introduce driver model support for SPI, SPI flash, cros_ec Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 01/25] sandbox: Convert SPI flash emulation to use sf_params Simon Glass
2014-08-25  9:24   ` Jagan Teki
2014-07-15  0:56 ` [U-Boot] [PATCH 02/25] sandbox: config: Enable all SPI flash chips Simon Glass
2014-08-25  9:24   ` Jagan Teki
2014-07-15  0:56 ` [U-Boot] [PATCH 03/25] sandbox: dts: Add a SPI device and cros_ec device Simon Glass
2014-08-25  9:32   ` Jagan Teki
2014-07-15  0:56 ` [U-Boot] [PATCH 04/25] dm: spi: Move cmd device code into its own function Simon Glass
2014-08-25 18:31   ` Jagan Teki
2014-09-02 19:22     ` Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 05/25] spi: Add brackets and tidy defines in spi.h Simon Glass
2014-08-25  9:34   ` Jagan Teki
2014-07-15  0:56 ` [U-Boot] [PATCH 06/25] dm: spi: Add a uclass for SPI Simon Glass
2014-07-15  8:26   ` Pavel Herrmann
2014-07-17  5:39     ` Simon Glass
2014-07-17  7:57       ` Pavel Herrmann
2014-07-17 15:26         ` Simon Glass
2014-07-17 18:01           ` Pavel Herrmann
2014-07-17 18:29             ` Pavel Herrmann
2014-07-21  2:17               ` Simon Glass
2014-07-21  2:15             ` Simon Glass
2014-08-11 21:46   ` Daniel Schwierzeck [this message]
2014-08-28  8:58   ` Jagan Teki
2014-08-29 23:38     ` Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 07/25] dm: sandbox: Add a SPI emulation uclass Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 08/25] dm: Remove spi_init() from board_r.c when using driver model Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 09/25] dm: Add spi.h header to a few files Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 10/25] dm: spi: Adjust cmd_spi to work with driver model Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 11/25] dm: sandbox: spi: Move to " Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 12/25] dm: spi: Add documentation on how to convert over SPI drivers Simon Glass
2014-08-28 11:32   ` Jagan Teki
2014-09-01  5:06     ` Simon Glass
2014-09-01  6:45       ` Jagan Teki
2014-09-02  0:24         ` Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 13/25] dm: exynos: Convert SPI to driver model Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 14/25] sf: Add an empty entry to the parameter list Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 15/25] sf: Tidy up public and private header files Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 16/25] spi: Use error return value in sf_ops Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 17/25] dm: sf: Add a uclass for SPI flash Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 18/25] dm: Convert spi_flash_probe() and 'sf probe' to use driver model Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 19/25] dm: sf: sandbox: Convert SPI flash driver to " Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 20/25] dm: exynos: config: Use driver model for SPI flash Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 21/25] dm: spi: Add tests Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 22/25] dm: sf: Add tests for SPI flash Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 23/25] dm: cros_ec: Add support for driver model Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 24/25] dm: sandbox: cros_ec: Move sandbox cros_ec to driver module Simon Glass
2014-07-15  0:56 ` [U-Boot] [PATCH 25/25] dm: exynos: cros_ec: Move cros_ec_spi to driver model Simon Glass
2014-08-09 21:29 ` [U-Boot] [PATCH 0/25] Introduce driver model support for SPI, SPI flash, cros_ec Simon Glass
2014-08-10  9:16   ` Jagan Teki
2014-08-11 19:55     ` Simon Glass
2014-09-15  1:03       ` Simon Glass

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=53E9399E.6000101@gmail.com \
    --to=daniel.schwierzeck@gmail.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.