aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorMika Westerberg <mika.westerberg@linux.intel.com>2016-02-08 10:14:30 -0500
committerMark Brown <broonie@kernel.org>2016-02-09 14:01:07 -0500
commitc1e4a53c6b8161ded3a44e3352ef38206d0967ea (patch)
tree1f8debab51784cf7117842bd6574fdf2adf702ea /drivers/spi
parent0c27d9cf7245d832d3d34f289c1bcd4f7f3fbd30 (diff)
spi: pxa2xx: Move chip select control bits into lpss_config structure
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 <mika.westerberg@linux.intel.com> Reviewed-by: Jarkko Nikula <jarkko.nikula@linux.intel.com> Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/spi-pxa2xx.c64
1 files changed, 40 insertions, 24 deletions
diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c
index 7d6d3b74d25b..81d68e01046a 100644
--- a/drivers/spi/spi-pxa2xx.c
+++ b/drivers/spi/spi-pxa2xx.c
@@ -65,8 +65,6 @@ MODULE_ALIAS("platform:pxa2xx-spi");
65#define LPSS_GENERAL_REG_RXTO_HOLDOFF_DISABLE BIT(24) 65#define LPSS_GENERAL_REG_RXTO_HOLDOFF_DISABLE BIT(24)
66#define LPSS_CS_CONTROL_SW_MODE BIT(0) 66#define LPSS_CS_CONTROL_SW_MODE BIT(0)
67#define LPSS_CS_CONTROL_CS_HIGH BIT(1) 67#define LPSS_CS_CONTROL_CS_HIGH BIT(1)
68#define LPSS_CS_CONTROL_CS_SEL_SHIFT 8
69#define LPSS_CS_CONTROL_CS_SEL_MASK (3 << LPSS_CS_CONTROL_CS_SEL_SHIFT)
70#define LPSS_CAPS_CS_EN_SHIFT 9 68#define LPSS_CAPS_CS_EN_SHIFT 9
71#define LPSS_CAPS_CS_EN_MASK (0xf << LPSS_CAPS_CS_EN_SHIFT) 69#define LPSS_CAPS_CS_EN_MASK (0xf << LPSS_CAPS_CS_EN_SHIFT)
72 70
@@ -82,6 +80,9 @@ struct lpss_config {
82 u32 rx_threshold; 80 u32 rx_threshold;
83 u32 tx_threshold_lo; 81 u32 tx_threshold_lo;
84 u32 tx_threshold_hi; 82 u32 tx_threshold_hi;
83 /* Chip select control */
84 unsigned cs_sel_shift;
85 unsigned cs_sel_mask;
85}; 86};
86 87
87/* Keep these sorted with enum pxa_ssp_type */ 88/* Keep these sorted with enum pxa_ssp_type */
@@ -125,6 +126,8 @@ static const struct lpss_config lpss_platforms[] = {
125 .rx_threshold = 1, 126 .rx_threshold = 1,
126 .tx_threshold_lo = 16, 127 .tx_threshold_lo = 16,
127 .tx_threshold_hi = 48, 128 .tx_threshold_hi = 48,
129 .cs_sel_shift = 8,
130 .cs_sel_mask = 3 << 8,
128 }, 131 },
129}; 132};
130 133
@@ -288,37 +291,50 @@ static void lpss_ssp_setup(struct driver_data *drv_data)
288 } 291 }
289} 292}
290 293
294static void lpss_ssp_select_cs(struct driver_data *drv_data,
295 const struct lpss_config *config)
296{
297 u32 value, cs;
298
299 if (!config->cs_sel_mask)
300 return;
301
302 value = __lpss_ssp_read_priv(drv_data, config->reg_cs_ctrl);
303
304 cs = drv_data->cur_msg->spi->chip_select;
305 cs <<= config->cs_sel_shift;
306 if (cs != (value & config->cs_sel_mask)) {
307 /*
308 * When switching another chip select output active the
309 * output must be selected first and wait 2 ssp_clk cycles
310 * before changing state to active. Otherwise a short
311 * glitch will occur on the previous chip select since
312 * output select is latched but state control is not.
313 */
314 value &= ~config->cs_sel_mask;
315 value |= cs;
316 __lpss_ssp_write_priv(drv_data,
317 config->reg_cs_ctrl, value);
318 ndelay(1000000000 /
319 (drv_data->master->max_speed_hz / 2));
320 }
321}
322
291static void lpss_ssp_cs_control(struct driver_data *drv_data, bool enable) 323static void lpss_ssp_cs_control(struct driver_data *drv_data, bool enable)
292{ 324{
293 const struct lpss_config *config; 325 const struct lpss_config *config;
294 u32 value, cs; 326 u32 value;
295 327
296 config = lpss_get_config(drv_data); 328 config = lpss_get_config(drv_data);
297 329
330 if (enable)
331 lpss_ssp_select_cs(drv_data, config);
332
298 value = __lpss_ssp_read_priv(drv_data, config->reg_cs_ctrl); 333 value = __lpss_ssp_read_priv(drv_data, config->reg_cs_ctrl);
299 if (enable) { 334 if (enable)
300 cs = drv_data->cur_msg->spi->chip_select;
301 cs <<= LPSS_CS_CONTROL_CS_SEL_SHIFT;
302 if (cs != (value & LPSS_CS_CONTROL_CS_SEL_MASK)) {
303 /*
304 * When switching another chip select output active
305 * the output must be selected first and wait 2 ssp_clk
306 * cycles before changing state to active. Otherwise
307 * a short glitch will occur on the previous chip
308 * select since output select is latched but state
309 * control is not.
310 */
311 value &= ~LPSS_CS_CONTROL_CS_SEL_MASK;
312 value |= cs;
313 __lpss_ssp_write_priv(drv_data,
314 config->reg_cs_ctrl, value);
315 ndelay(1000000000 /
316 (drv_data->master->max_speed_hz / 2));
317 }
318 value &= ~LPSS_CS_CONTROL_CS_HIGH; 335 value &= ~LPSS_CS_CONTROL_CS_HIGH;
319 } else { 336 else
320 value |= LPSS_CS_CONTROL_CS_HIGH; 337 value |= LPSS_CS_CONTROL_CS_HIGH;
321 }
322 __lpss_ssp_write_priv(drv_data, config->reg_cs_ctrl, value); 338 __lpss_ssp_write_priv(drv_data, config->reg_cs_ctrl, value);
323} 339}
324 340