From patchwork Mon Feb 8 15:14:30 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mika Westerberg X-Patchwork-Id: 8250821 Return-Path: X-Original-To: patchwork-linux-spi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id D9333BEEE5 for ; Mon, 8 Feb 2016 15:15:25 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E07B8202B8 for ; Mon, 8 Feb 2016 15:15:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C784C203C3 for ; Mon, 8 Feb 2016 15:15:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752783AbcBHPOp (ORCPT ); Mon, 8 Feb 2016 10:14:45 -0500 Received: from mga03.intel.com ([134.134.136.65]:9771 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751881AbcBHPOn (ORCPT ); Mon, 8 Feb 2016 10:14:43 -0500 Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga103.jf.intel.com with ESMTP; 08 Feb 2016 07:14:44 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.22,416,1449561600"; d="scan'208";a="879548855" Received: from black.fi.intel.com ([10.237.72.93]) by orsmga001.jf.intel.com with ESMTP; 08 Feb 2016 07:14:34 -0800 Received: by black.fi.intel.com (Postfix, from userid 1001) id 4443338C; Mon, 8 Feb 2016 17:14:32 +0200 (EET) From: Mika Westerberg To: Mark Brown Cc: Daniel Mack , Haojian Zhuang , Robert Jarzmik , Jarkko Nikula , Mika Westerberg , Bastien Nocera , linux-spi@vger.kernel.org, linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 3/4] spi: pxa2xx: Move chip select control bits into lpss_config structure Date: Mon, 8 Feb 2016 17:14:30 +0200 Message-Id: <1454944471-50119-4-git-send-email-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.7.0 In-Reply-To: <1454944471-50119-1-git-send-email-mika.westerberg@linux.intel.com> References: <1454944471-50119-1-git-send-email-mika.westerberg@linux.intel.com> Sender: linux-spi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-spi@vger.kernel.org X-Spam-Status: No, score=-7.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Some Intel LPSS SPI controllers, like the one in Braswell has these bits in a different location so move these bits to be part of the LPSS configuration. Since not all LPSS SPI controllers support multiple native chip selects we refactor selecting chip select to its own function and check control->cs_sel_mask before switching to another chip select. Signed-off-by: Mika Westerberg Reviewed-by: Jarkko Nikula --- drivers/spi/spi-pxa2xx.c | 64 ++++++++++++++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c index 7c795cfbbf9d..6d4adc906f52 100644 --- a/drivers/spi/spi-pxa2xx.c +++ b/drivers/spi/spi-pxa2xx.c @@ -65,8 +65,6 @@ MODULE_ALIAS("platform:pxa2xx-spi"); #define LPSS_GENERAL_REG_RXTO_HOLDOFF_DISABLE BIT(24) #define LPSS_CS_CONTROL_SW_MODE BIT(0) #define LPSS_CS_CONTROL_CS_HIGH BIT(1) -#define LPSS_CS_CONTROL_CS_SEL_SHIFT 8 -#define LPSS_CS_CONTROL_CS_SEL_MASK (3 << LPSS_CS_CONTROL_CS_SEL_SHIFT) #define LPSS_CAPS_CS_EN_SHIFT 9 #define LPSS_CAPS_CS_EN_MASK (0xf << LPSS_CAPS_CS_EN_SHIFT) @@ -82,6 +80,9 @@ struct lpss_config { u32 rx_threshold; u32 tx_threshold_lo; u32 tx_threshold_hi; + /* Chip select control */ + unsigned cs_sel_shift; + unsigned cs_sel_mask; }; /* Keep these sorted with enum pxa_ssp_type */ @@ -125,6 +126,8 @@ static const struct lpss_config lpss_platforms[] = { .rx_threshold = 1, .tx_threshold_lo = 16, .tx_threshold_hi = 48, + .cs_sel_shift = 8, + .cs_sel_mask = 3 << 8, }, }; @@ -288,37 +291,50 @@ static void lpss_ssp_setup(struct driver_data *drv_data) } } +static void lpss_ssp_select_cs(struct driver_data *drv_data, + const struct lpss_config *config) +{ + u32 value, cs; + + if (!config->cs_sel_mask) + return; + + value = __lpss_ssp_read_priv(drv_data, config->reg_cs_ctrl); + + cs = drv_data->cur_msg->spi->chip_select; + cs <<= config->cs_sel_shift; + if (cs != (value & config->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 &= ~config->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)); + } +} + static void lpss_ssp_cs_control(struct driver_data *drv_data, bool enable) { const struct lpss_config *config; - u32 value, cs; + u32 value; config = lpss_get_config(drv_data); + if (enable) + lpss_ssp_select_cs(drv_data, config); + value = __lpss_ssp_read_priv(drv_data, config->reg_cs_ctrl); - if (enable) { - cs = drv_data->cur_msg->spi->chip_select; - cs <<= LPSS_CS_CONTROL_CS_SEL_SHIFT; - if (cs != (value & LPSS_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 &= ~LPSS_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)); - } + if (enable) value &= ~LPSS_CS_CONTROL_CS_HIGH; - } else { + else value |= LPSS_CS_CONTROL_CS_HIGH; - } __lpss_ssp_write_priv(drv_data, config->reg_cs_ctrl, value); }