linux-spi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jarkko Nikula <jarkko.nikula-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
To: linux-spi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	Daniel Mack <daniel-cYrQPVfZoowdnm+yROfE0A@public.gmane.org>,
	Haojian Zhuang
	<haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Robert Jarzmik <robert.jarzmik-GANU6spQydw@public.gmane.org>,
	Jarkko Nikula
	<jarkko.nikula-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Subject: [PATCH 6/7] spi: pxa2xx: Add support for multiple LPSS chip select signals
Date: Thu, 22 Oct 2015 16:44:44 +0300	[thread overview]
Message-ID: <1445521485-2029-6-git-send-email-jarkko.nikula@linux.intel.com> (raw)
In-Reply-To: <1445521485-2029-1-git-send-email-jarkko.nikula-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>

LPSS SPI devices in a successor of Intel Sunrisepoint can have up to 4 chip
selects per port. SPI capabilities register bits 12:9 tell which are
enabled. For simplicity we assume chip selects are enabled one after
another without disabled chip selects between. For instance CS0 | CS1 | CS2
but not CS0 | CS1 | CS3.

This patch adds support for detecting the number of enabled chip selects
and adds output control to those LPSS SPI ports that have more than one
chip select signal.

Signed-off-by: Jarkko Nikula <jarkko.nikula-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
---
 drivers/spi/spi-pxa2xx.c | 48 +++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 43 insertions(+), 5 deletions(-)

diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c
index 672963653d3b..6851649d1b15 100644
--- a/drivers/spi/spi-pxa2xx.c
+++ b/drivers/spi/spi-pxa2xx.c
@@ -13,6 +13,7 @@
  * GNU General Public License for more details.
  */
 
+#include <linux/bitops.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/device.h>
@@ -64,6 +65,10 @@ MODULE_ALIAS("platform:pxa2xx-spi");
 #define GENERAL_REG_RXTO_HOLDOFF_DISABLE	BIT(24)
 #define SPI_CS_CONTROL_SW_MODE			BIT(0)
 #define SPI_CS_CONTROL_CS_HIGH			BIT(1)
+#define SPI_CS_CONTROL_CS_SEL_SHIFT		8
+#define SPI_CS_CONTROL_CS_SEL_MASK		(3 << SPI_CS_CONTROL_CS_SEL_SHIFT)
+#define SPI_CAPS_CS_EN_SHIFT			9
+#define SPI_CAPS_CS_EN_MASK			(0xf << SPI_CAPS_CS_EN_SHIFT)
 
 struct lpss_config {
 	/* LPSS offset from drv_data->ioaddr */
@@ -72,6 +77,7 @@ struct lpss_config {
 	int reg_general;
 	int reg_ssp;
 	int reg_cs_ctrl;
+	int reg_capabilities;
 	/* FIFO thresholds */
 	u32 rx_threshold;
 	u32 tx_threshold_lo;
@@ -85,6 +91,7 @@ static const struct lpss_config lpss_platforms[] = {
 		.reg_general = 0x08,
 		.reg_ssp = 0x0c,
 		.reg_cs_ctrl = 0x18,
+		.reg_capabilities = -1,
 		.rx_threshold = 64,
 		.tx_threshold_lo = 160,
 		.tx_threshold_hi = 224,
@@ -94,6 +101,7 @@ static const struct lpss_config lpss_platforms[] = {
 		.reg_general = 0x08,
 		.reg_ssp = 0x0c,
 		.reg_cs_ctrl = 0x18,
+		.reg_capabilities = -1,
 		.rx_threshold = 64,
 		.tx_threshold_lo = 160,
 		.tx_threshold_hi = 224,
@@ -103,6 +111,7 @@ static const struct lpss_config lpss_platforms[] = {
 		.reg_general = -1,
 		.reg_ssp = 0x20,
 		.reg_cs_ctrl = 0x24,
+		.reg_capabilities = 0xfc,
 		.rx_threshold = 1,
 		.tx_threshold_lo = 32,
 		.tx_threshold_hi = 56,
@@ -271,15 +280,34 @@ static void lpss_ssp_setup(struct driver_data *drv_data)
 static void lpss_ssp_cs_control(struct driver_data *drv_data, bool enable)
 {
 	const struct lpss_config *config;
-	u32 value;
+	u32 value, cs;
 
 	config = lpss_get_config(drv_data);
 
 	value = __lpss_ssp_read_priv(drv_data, config->reg_cs_ctrl);
-	if (enable)
+	if (enable) {
+		cs = drv_data->cur_msg->spi->chip_select;
+		cs <<= SPI_CS_CONTROL_CS_SEL_SHIFT;
+		if (cs != (value & SPI_CS_CONTROL_CS_SEL_MASK)) {
+			/*
+			 * When switching another chip select output active
+			 * the output must be selected first and wait 2 ssp_clk
+			 * cycles before changing state to active. Otherwise
+			 * a short glitch will occur on the previous chip
+			 * select since output select is latched but state
+			 * control is not.
+			 */
+			value &= ~SPI_CS_CONTROL_CS_SEL_MASK;
+			value |= cs;
+			__lpss_ssp_write_priv(drv_data,
+					      config->reg_cs_ctrl, value);
+			ndelay(1000000000 /
+			       (drv_data->master->max_speed_hz / 2));
+		}
 		value &= ~SPI_CS_CONTROL_CS_HIGH;
-	else
+	} else {
 		value |= SPI_CS_CONTROL_CS_HIGH;
+	}
 	__lpss_ssp_write_priv(drv_data, config->reg_cs_ctrl, value);
 }
 
@@ -1383,6 +1411,7 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
 	struct spi_master *master;
 	struct driver_data *drv_data;
 	struct ssp_device *ssp;
+	const struct lpss_config *config;
 	int status;
 	u32 tmp;
 
@@ -1422,7 +1451,6 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
 	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP;
 
 	master->bus_num = ssp->port_id;
-	master->num_chipselect = platform_info->num_chipselect;
 	master->dma_alignment = DMA_ALIGNMENT;
 	master->cleanup = cleanup;
 	master->setup = setup;
@@ -1505,8 +1533,18 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
 	if (!is_quark_x1000_ssp(drv_data))
 		pxa2xx_spi_write(drv_data, SSPSP, 0);
 
-	if (is_lpss_ssp(drv_data))
+	if (is_lpss_ssp(drv_data)) {
 		lpss_ssp_setup(drv_data);
+		config = lpss_get_config(drv_data);
+		if (config->reg_capabilities >= 0) {
+			tmp = __lpss_ssp_read_priv(drv_data,
+						   config->reg_capabilities);
+			tmp &= SPI_CAPS_CS_EN_MASK;
+			tmp >>= SPI_CAPS_CS_EN_SHIFT;
+			platform_info->num_chipselect = ffz(tmp);
+		}
+	}
+	master->num_chipselect = platform_info->num_chipselect;
 
 	tasklet_init(&drv_data->pump_transfers, pump_transfers,
 		     (unsigned long)drv_data);
-- 
2.6.1

--
To unsubscribe from this list: send the line "unsubscribe linux-spi" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

  parent reply	other threads:[~2015-10-22 13:44 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-22 13:44 [PATCH 1/7] spi: pxa2xx: move debug messages to pump_transfer() Jarkko Nikula
     [not found] ` <1445521485-2029-1-git-send-email-jarkko.nikula-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2015-10-22 13:44   ` [PATCH 2/7] spi: pxa2xx: derive struct chip_data from struct drv_data Jarkko Nikula
     [not found]     ` <1445521485-2029-2-git-send-email-jarkko.nikula-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2015-10-22 23:57       ` Applied "spi: pxa2xx: derive struct chip_data from struct drv_data" to the spi tree Mark Brown
2015-10-25 11:42       ` [PATCH 2/7] spi: pxa2xx: derive struct chip_data from struct drv_data Robert Jarzmik
2015-10-22 13:44   ` [PATCH 3/7] spi: pxa2xx: Convert unique ID string of ACPI device as unsigned integer Jarkko Nikula
     [not found]     ` <1445521485-2029-3-git-send-email-jarkko.nikula-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2015-10-22 23:57       ` Applied "spi: pxa2xx: Convert unique ID string of ACPI device as unsigned integer" to the spi tree Mark Brown
2015-10-22 13:44   ` [PATCH 4/7] spi: pxa2xx: Save other reg_cs_ctrl bits when configuring chip select Jarkko Nikula
     [not found]     ` <1445521485-2029-4-git-send-email-jarkko.nikula-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2015-10-22 23:57       ` Applied "spi: pxa2xx: Save other reg_cs_ctrl bits when configuring chip select" to the spi tree Mark Brown
2015-10-25 11:49       ` [PATCH 4/7] spi: pxa2xx: Save other reg_cs_ctrl bits when configuring chip select Robert Jarzmik
2015-10-22 13:44   ` [PATCH 5/7] spi: pxa2xx: Align a few defines Jarkko Nikula
     [not found]     ` <1445521485-2029-5-git-send-email-jarkko.nikula-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2015-10-22 23:57       ` Applied "spi: pxa2xx: Align a few defines" to the spi tree Mark Brown
2015-10-25 11:50       ` [PATCH 5/7] spi: pxa2xx: Align a few defines Robert Jarzmik
2015-10-22 13:44   ` Jarkko Nikula [this message]
     [not found]     ` <1445521485-2029-6-git-send-email-jarkko.nikula-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2015-10-25 12:02       ` [PATCH 6/7] spi: pxa2xx: Add support for multiple LPSS chip select signals Robert Jarzmik
     [not found]         ` <87bnbnkvg9.fsf-4ty26DBLk+jEm7gnYqmdkQ@public.gmane.org>
2015-10-26  9:35           ` Jarkko Nikula
2015-10-22 13:44   ` [PATCH 7/7] spi: pxa2xx: Add support for Intel Broxton Jarkko Nikula
     [not found]     ` <1445521485-2029-7-git-send-email-jarkko.nikula-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2015-10-30  2:20       ` Mark Brown
2015-10-22 23:57   ` Applied "spi: pxa2xx: move debug messages to pump_transfer()" to the spi tree Mark Brown
2015-10-25 11:39   ` [PATCH 1/7] spi: pxa2xx: move debug messages to pump_transfer() Robert Jarzmik

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=1445521485-2029-6-git-send-email-jarkko.nikula@linux.intel.com \
    --to=jarkko.nikula-vuqaysv1563yd54fqh9/ca@public.gmane.org \
    --cc=broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
    --cc=daniel-cYrQPVfZoowdnm+yROfE0A@public.gmane.org \
    --cc=haojian.zhuang-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=linux-spi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=robert.jarzmik-GANU6spQydw@public.gmane.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).