[PATCH v2 3/4] spi: mediatek: Add spi bus for Mediatek MT8173
Sascha Hauer
s.hauer at pengutronix.de
Tue Jun 30 22:07:49 PDT 2015
On Wed, Jul 01, 2015 at 12:06:02PM +0800, Daniel Kurtz wrote:
> Hi Leilk,
>
> Please see comments inline...
>
> On Mon, Jun 29, 2015 at 9:04 PM, Leilk Liu <leilk.liu at mediatek.com> wrote:
> > This patch adds basic spi bus for MT8173.
> >
> > Signed-off-by: Leilk Liu <leilk.liu at mediatek.com>
> > Signed-off-by: Eddie Huang <eddie.huang at mediatek.com>
> > ---
> > drivers/spi/Kconfig | 9 +
> > drivers/spi/Makefile | 1 +
> > drivers/spi/spi-mt65xx.c | 656 +++++++++++++++++++++++++++++++++++++++++++++++
> > 3 files changed, 666 insertions(+)
> > create mode 100644 drivers/spi/spi-mt65xx.c
> >
> > diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
> > index 198f96b..06f9514 100644
> > --- a/drivers/spi/Kconfig
> > +++ b/drivers/spi/Kconfig
> > @@ -324,6 +324,15 @@ config SPI_MESON_SPIFC
> > This enables master mode support for the SPIFC (SPI flash
> > controller) available in Amlogic Meson SoCs.
> >
> > +config SPI_MT65XX
> > + tristate "MediaTek SPI controller"
> > + depends on ARCH_MEDIATEK || COMPILE_TEST
> > + help
> > + This selects the MediaTek(R) SPI bus driver.
> > + If you want to use MediaTek(R) SPI interface,
> > + say Y or M here.If you are not sure, say N.
> > + SPI drivers for Mediatek mt65XX series ARM SoCs.
> > +
> > config SPI_OC_TINY
> > tristate "OpenCores tiny SPI"
> > depends on GPIOLIB
> > diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
> > index d8cbf65..ab332ef 100644
> > --- a/drivers/spi/Makefile
> > +++ b/drivers/spi/Makefile
> > @@ -48,6 +48,7 @@ obj-$(CONFIG_SPI_MESON_SPIFC) += spi-meson-spifc.o
> > obj-$(CONFIG_SPI_MPC512x_PSC) += spi-mpc512x-psc.o
> > obj-$(CONFIG_SPI_MPC52xx_PSC) += spi-mpc52xx-psc.o
> > obj-$(CONFIG_SPI_MPC52xx) += spi-mpc52xx.o
> > +obj-$(CONFIG_SPI_MT65XX) += spi-mt65xx.o
> > obj-$(CONFIG_SPI_MXS) += spi-mxs.o
> > obj-$(CONFIG_SPI_NUC900) += spi-nuc900.o
> > obj-$(CONFIG_SPI_OC_TINY) += spi-oc-tiny.o
> > diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
> > new file mode 100644
> > index 0000000..6cb54587
> > --- /dev/null
> > +++ b/drivers/spi/spi-mt65xx.c
> > @@ -0,0 +1,656 @@
> > +/*
> > + * Copyright (c) 2015 MediaTek Inc.
> > + * Author: Leilk Liu <leilk.liu at mediatek.com>
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License version 2 as
> > + * published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> > + * GNU General Public License for more details.
> > + */
> > +
> > +#include <linux/init.h>
> > +#include <linux/module.h>
> > +#include <linux/device.h>
> > +#include <linux/ioport.h>
> > +#include <linux/errno.h>
> > +#include <linux/spi/spi.h>
> > +#include <linux/workqueue.h>
> > +#include <linux/dma-mapping.h>
> > +#include <linux/platform_device.h>
> > +#include <linux/interrupt.h>
> > +#include <linux/irqreturn.h>
> > +#include <linux/types.h>
> > +#include <linux/delay.h>
> > +#include <linux/clk.h>
> > +#include <linux/err.h>
> > +#include <linux/io.h>
> > +#include <linux/sched.h>
> > +#include <linux/of.h>
> > +#include <linux/of_irq.h>
> > +#include <linux/of_address.h>
> > +#include <linux/of_gpio.h>
> > +#include <linux/kernel.h>
> > +#include <linux/gpio.h>
> > +#include <linux/module.h>
> > +#include <linux/pm_runtime.h>
>
> It would be nicer if you can alphabetize these headers.
>
> > +
> > +#define SPI_CFG0_REG 0x0000
> > +#define SPI_CFG1_REG 0x0004
> > +#define SPI_TX_SRC_REG 0x0008
> > +#define SPI_RX_DST_REG 0x000c
> > +#define SPI_CMD_REG 0x0018
> > +#define SPI_STATUS0_REG 0x001c
> > +#define SPI_PAD_SEL_REG 0x0024
> > +
> > +#define SPI_CFG0_SCK_HIGH_OFFSET 0
> > +#define SPI_CFG0_SCK_LOW_OFFSET 8
> > +#define SPI_CFG0_CS_HOLD_OFFSET 16
> > +#define SPI_CFG0_CS_SETUP_OFFSET 24
> > +
> > +#define SPI_CFG0_SCK_HIGH_MASK 0xff
> > +#define SPI_CFG0_SCK_LOW_MASK 0xff00
> > +#define SPI_CFG0_CS_HOLD_MASK 0xff0000
> > +#define SPI_CFG0_CS_SETUP_MASK 0xff000000
> > +
> > +#define SPI_CFG1_CS_IDLE_OFFSET 0
> > +#define SPI_CFG1_PACKET_LOOP_OFFSET 8
> > +#define SPI_CFG1_PACKET_LENGTH_OFFSET 16
> > +#define SPI_CFG1_GET_TICK_DLY_OFFSET 30
> > +
> > +#define SPI_CFG1_CS_IDLE_MASK 0xff
> > +#define SPI_CFG1_PACKET_LOOP_MASK 0xff00
> > +#define SPI_CFG1_PACKET_LENGTH_MASK 0x3ff0000
> > +#define SPI_CFG1_GET_TICK_DLY_MASK 0xc0000000
> > +
> > +#define SPI_CMD_ACT_OFFSET 0
> > +#define SPI_CMD_RESUME_OFFSET 1
> > +#define SPI_CMD_RST_OFFSET 2
> > +#define SPI_CMD_PAUSE_EN_OFFSET 4
> > +#define SPI_CMD_DEASSERT_OFFSET 5
> > +#define SPI_CMD_CPHA_OFFSET 8
> > +#define SPI_CMD_CPOL_OFFSET 9
> > +#define SPI_CMD_RX_DMA_OFFSET 10
> > +#define SPI_CMD_TX_DMA_OFFSET 11
> > +#define SPI_CMD_TXMSBF_OFFSET 12
> > +#define SPI_CMD_RXMSBF_OFFSET 13
> > +#define SPI_CMD_RX_ENDIAN_OFFSET 14
> > +#define SPI_CMD_TX_ENDIAN_OFFSET 15
> > +#define SPI_CMD_FINISH_IE_OFFSET 16
> > +#define SPI_CMD_PAUSE_IE_OFFSET 17
> > +
> > +#define SPI_CMD_RST_MASK 0x4
> > +#define SPI_CMD_PAUSE_EN_MASK 0x10
> > +#define SPI_CMD_DEASSERT_MASK 0x20
> > +#define SPI_CMD_CPHA_MASK 0x100
> > +#define SPI_CMD_CPOL_MASK 0x200
> > +#define SPI_CMD_RX_DMA_MASK 0x400
> > +#define SPI_CMD_TX_DMA_MASK 0x800
> > +#define SPI_CMD_TXMSBF_MASK 0x1000
> > +#define SPI_CMD_RXMSBF_MASK 0x2000
> > +#define SPI_CMD_RX_ENDIAN_MASK 0x4000
> > +#define SPI_CMD_TX_ENDIAN_MASK 0x8000
> > +#define SPI_CMD_FINISH_IE_MASK 0x10000
>
> Use the BIT() macro do define these bit masks.
> In fact, for these 1-bit fields, just use the MASK rather than "(1 <<
> *_OFFSET)" when setting/clearing the bits in code.
>
> > +
> > +#define COMPAT_MT6589 (0x1 << 0)
> > +#define COMPAT_MT8135 (0x1 << 1)
> > +#define COMPAT_MT8173 (0x1 << 2)
>
> Rather than define per-platform "COMPAT" flags, I think it would be
> better to define these as a set of quirks.
> Individual platforms would then specify a mask indicating which quirks
> they support.
>
> In this case, there are only two, and both are present on mt8173, but
> not on the other 2 listed parts:
> MTK_SPI_QUIRK_PAD_SELECT
> MTK_SPI_QUIRK_MUST_TX /* Must explicitly send dummy Tx bytes to do
> Rx only transfer */
>
> For MTK_SPI_QUIRK_MUST_TX, I think it just means that we must set the
> SPI_MASTER_MUST_TX flag when registering the spi_master?
>
> > +
> > +#define MT8173_MAX_PAD_SEL 3
>
> I'm not exactly sure how to deal with PAD_SEL either:
>
> The MT8173 SPI device supports four SPI ports.
> Each port has the full complement of 4 signals (nSS, CLK, MISO, MOSI).
> However, only one can be selected at a time via the "PAD_SEL" register.
> In addition, the SPI function for the SPI port pins must be enabled
> for the corresponding GPIOs via pinctl.
> If the nSS pin has its SPI function selected, it will be controlled
> automatically by SPI hardware.
>
> Relying on hardware control of the SPI nSS pin seems quite limiting -
> it means each SPI port can only control a single slave device.
> I would think that allowing any GPIO to act as nSS would be much more
> flexible, since then each SPI port could truly be a multi-slave bus.
> I also believe the standard linux SPI infrastructure has support for
> using GPIOs in this way.
> How is this handled for other platforms (using built-in nSS versus
> using GPIOs as nSS)?
Often Hardware has its own idea when to enable/disable the chipselect.
Some Freescale hardware just raises the chipselect when it's out of data
which means that delays in the software causes arbitrary CS toggles.
With GPIOs as chipselects there are less possibilities to get it wrong.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
More information about the linux-arm-kernel
mailing list