aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorBrian Niebuhr <bniebuhr@efjohnson.com>2010-08-13 03:57:23 -0400
committerSekhar Nori <nsekhar@ti.com>2010-11-18 08:08:25 -0500
commit7fe0092b1f55f58a749d68ace3a3597e8a2a9163 (patch)
tree95df072f92ab7766aba26869d42777f817d3c6e1 /drivers/spi
parent23853973d9b76eb8b3cf46157689bc6187e141d9 (diff)
spi: davinci: simplify prescalar calculation
Simplify pre-scalar calculation and move it into a seprate function. Refuse to correct invalid pre-scalar values silently as this might lead to unexpected bugs and lower performance. Instead an error will force users to dig into the root-cause of the issue. While at it, remove some device specific checks on the maximum SPI frequency. As the driver supports the SPI interface implemented on various devices, it should only take care of core SPI limitations and leave the device specific handling to platform code. Signed-off-by: Brian Niebuhr <bniebuhr@efjohnson.com> Tested-By: Michael Williamson <michael.williamson@criticallink.com> Signed-off-by: Sekhar Nori <nsekhar@ti.com>
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/davinci_spi.c53
1 files changed, 31 insertions, 22 deletions
diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c
index d5d7014e6ae2..17269ad54a99 100644
--- a/drivers/spi/davinci_spi.c
+++ b/drivers/spi/davinci_spi.c
@@ -53,6 +53,7 @@
53#define SPIFMT_WDELAY_MASK 0x3f000000u 53#define SPIFMT_WDELAY_MASK 0x3f000000u
54#define SPIFMT_WDELAY_SHIFT 24 54#define SPIFMT_WDELAY_SHIFT 24
55#define SPIFMT_CHARLEN_MASK 0x0000001Fu 55#define SPIFMT_CHARLEN_MASK 0x0000001Fu
56#define SPIFMT_PRESCALE_SHIFT 8
56 57
57 58
58/* SPIPC0 */ 59/* SPIPC0 */
@@ -267,6 +268,29 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value)
267} 268}
268 269
269/** 270/**
271 * davinci_spi_get_prescale - Calculates the correct prescale value
272 * @maxspeed_hz: the maximum rate the SPI clock can run at
273 *
274 * This function calculates the prescale value that generates a clock rate
275 * less than or equal to the specified maximum.
276 *
277 * Returns: calculated prescale - 1 for easy programming into SPI registers
278 * or negative error number if valid prescalar cannot be updated.
279 */
280static inline int davinci_spi_get_prescale(struct davinci_spi *davinci_spi,
281 u32 max_speed_hz)
282{
283 int ret;
284
285 ret = DIV_ROUND_UP(clk_get_rate(davinci_spi->clk), max_speed_hz);
286
287 if (ret < 3 || ret > 256)
288 return -EINVAL;
289
290 return ret - 1;
291}
292
293/**
270 * davinci_spi_setup_transfer - This functions will determine transfer method 294 * davinci_spi_setup_transfer - This functions will determine transfer method
271 * @spi: spi device on which data transfer to be done 295 * @spi: spi device on which data transfer to be done
272 * @t: spi transfer in which transfer info is filled 296 * @t: spi transfer in which transfer info is filled
@@ -281,7 +305,7 @@ static int davinci_spi_setup_transfer(struct spi_device *spi,
281 305
282 struct davinci_spi *davinci_spi; 306 struct davinci_spi *davinci_spi;
283 u8 bits_per_word = 0; 307 u8 bits_per_word = 0;
284 u32 hz = 0, prescale = 0, clkspeed; 308 u32 hz = 0, prescale = 0;
285 309
286 davinci_spi = spi_master_get_devdata(spi->master); 310 davinci_spi = spi_master_get_devdata(spi->master);
287 311
@@ -312,21 +336,18 @@ static int davinci_spi_setup_transfer(struct spi_device *spi,
312 if (!hz) 336 if (!hz)
313 hz = spi->max_speed_hz; 337 hz = spi->max_speed_hz;
314 338
339 prescale = davinci_spi_get_prescale(davinci_spi, hz);
340 if (prescale < 0)
341 return prescale;
342
315 clear_fmt_bits(davinci_spi->base, SPIFMT_CHARLEN_MASK, 343 clear_fmt_bits(davinci_spi->base, SPIFMT_CHARLEN_MASK,
316 spi->chip_select); 344 spi->chip_select);
317 set_fmt_bits(davinci_spi->base, bits_per_word & 0x1f, 345 set_fmt_bits(davinci_spi->base, bits_per_word & 0x1f,
318 spi->chip_select); 346 spi->chip_select);
319 347
320 clkspeed = clk_get_rate(davinci_spi->clk);
321 if (hz > clkspeed / 2)
322 prescale = 1 << 8;
323 if (hz < clkspeed / 256)
324 prescale = 255 << 8;
325 if (!prescale)
326 prescale = ((clkspeed / hz - 1) << 8) & 0x0000ff00;
327
328 clear_fmt_bits(davinci_spi->base, 0x0000ff00, spi->chip_select); 348 clear_fmt_bits(davinci_spi->base, 0x0000ff00, spi->chip_select);
329 set_fmt_bits(davinci_spi->base, prescale, spi->chip_select); 349 set_fmt_bits(davinci_spi->base,
350 prescale << SPIFMT_PRESCALE_SHIFT, spi->chip_select);
330 351
331 return 0; 352 return 0;
332} 353}
@@ -413,10 +434,8 @@ static int davinci_spi_setup(struct spi_device *spi)
413 int retval; 434 int retval;
414 struct davinci_spi *davinci_spi; 435 struct davinci_spi *davinci_spi;
415 struct davinci_spi_dma *davinci_spi_dma; 436 struct davinci_spi_dma *davinci_spi_dma;
416 struct device *sdev;
417 437
418 davinci_spi = spi_master_get_devdata(spi->master); 438 davinci_spi = spi_master_get_devdata(spi->master);
419 sdev = davinci_spi->bitbang.master->dev.parent;
420 439
421 /* if bits per word length is zero then set it default 8 */ 440 /* if bits per word length is zero then set it default 8 */
422 if (!spi->bits_per_word) 441 if (!spi->bits_per_word)
@@ -436,16 +455,6 @@ static int davinci_spi_setup(struct spi_device *spi)
436 } 455 }
437 456
438 /* 457 /*
439 * SPI in DaVinci and DA8xx operate between
440 * 600 KHz and 50 MHz
441 */
442 if (spi->max_speed_hz < 600000 || spi->max_speed_hz > 50000000) {
443 dev_dbg(sdev, "Operating frequency is not in acceptable "
444 "range\n");
445 return -EINVAL;
446 }
447
448 /*
449 * Set up SPIFMTn register, unique to this chipselect. 458 * Set up SPIFMTn register, unique to this chipselect.
450 * 459 *
451 * NOTE: we could do all of these with one write. Also, some 460 * NOTE: we could do all of these with one write. Also, some