Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

spi: bitbang: switch to the generic implementation of transfer_one_message

Change the bitbang driver to use the generic implementation of
transfer_one_message. This simplifies the bitbang driver code and
provides benefits like the statistics in the generic implementation.

Successfully tested on a IMX6-based system (spi-imx) and on a MIPS-based
router (OpenWRT with spi-ath79).

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Heiner Kallweit and committed by
Mark Brown
00376865 e30d8f23

+36 -89
+36 -89
drivers/spi/spi-bitbang.c
··· 24 24 #include <linux/spi/spi.h> 25 25 #include <linux/spi/spi_bitbang.h> 26 26 27 + #define SPI_BITBANG_CS_DELAY 100 28 + 27 29 28 30 /*----------------------------------------------------------------------*/ 29 31 ··· 267 265 } 268 266 269 267 static int spi_bitbang_transfer_one(struct spi_master *master, 270 - struct spi_message *m) 268 + struct spi_device *spi, 269 + struct spi_transfer *transfer) 271 270 { 272 - struct spi_bitbang *bitbang; 273 - unsigned nsecs; 274 - struct spi_transfer *t = NULL; 275 - unsigned cs_change; 276 - int status; 277 - struct spi_device *spi = m->spi; 271 + struct spi_bitbang *bitbang = spi_master_get_devdata(master); 272 + int status = 0; 278 273 279 - bitbang = spi_master_get_devdata(master); 274 + if (bitbang->setup_transfer) { 275 + status = bitbang->setup_transfer(spi, transfer); 276 + if (status < 0) 277 + goto out; 278 + } 280 279 281 - /* FIXME this is made-up ... the correct value is known to 282 - * word-at-a-time bitbang code, and presumably chipselect() 283 - * should enforce these requirements too? 284 - */ 285 - nsecs = 100; 280 + if (transfer->len) 281 + status = bitbang->txrx_bufs(spi, transfer); 286 282 287 - cs_change = 1; 288 - status = 0; 289 - 290 - list_for_each_entry(t, &m->transfers, transfer_list) { 291 - 292 - if (bitbang->setup_transfer) { 293 - status = bitbang->setup_transfer(spi, t); 294 - if (status < 0) 295 - break; 296 - } 297 - 298 - /* set up default clock polarity, and activate chip; 299 - * this implicitly updates clock and spi modes as 300 - * previously recorded for this device via setup(). 301 - * (and also deselects any other chip that might be 302 - * selected ...) 303 - */ 304 - if (cs_change) { 305 - bitbang->chipselect(spi, BITBANG_CS_ACTIVE); 306 - ndelay(nsecs); 307 - } 308 - cs_change = t->cs_change; 309 - if (!t->tx_buf && !t->rx_buf && t->len) { 310 - status = -EINVAL; 311 - break; 312 - } 313 - 314 - /* transfer data. the lower level code handles any 315 - * new dma mappings it needs. our caller always gave 316 - * us dma-safe buffers. 317 - */ 318 - if (t->len) { 319 - /* REVISIT dma API still needs a designated 320 - * DMA_ADDR_INVALID; ~0 might be better. 321 - */ 322 - if (!m->is_dma_mapped) 323 - t->rx_dma = t->tx_dma = 0; 324 - status = bitbang->txrx_bufs(spi, t); 325 - } 326 - if (status > 0) 327 - m->actual_length += status; 328 - if (status != t->len) { 329 - /* always report some kind of error */ 330 - if (status >= 0) 331 - status = -EREMOTEIO; 332 - break; 333 - } 283 + if (status == transfer->len) 334 284 status = 0; 285 + else if (status >= 0) 286 + status = -EREMOTEIO; 335 287 336 - /* protocol tweaks before next transfer */ 337 - if (t->delay_usecs) 338 - udelay(t->delay_usecs); 339 - 340 - if (cs_change && 341 - !list_is_last(&t->transfer_list, &m->transfers)) { 342 - /* sometimes a short mid-message deselect of the chip 343 - * may be needed to terminate a mode or command 344 - */ 345 - ndelay(nsecs); 346 - bitbang->chipselect(spi, BITBANG_CS_INACTIVE); 347 - ndelay(nsecs); 348 - } 349 - } 350 - 351 - m->status = status; 352 - 353 - /* normally deactivate chipselect ... unless no error and 354 - * cs_change has hinted that the next message will probably 355 - * be for this chip too. 356 - */ 357 - if (!(status == 0 && cs_change)) { 358 - ndelay(nsecs); 359 - bitbang->chipselect(spi, BITBANG_CS_INACTIVE); 360 - ndelay(nsecs); 361 - } 362 - 363 - spi_finalize_current_message(master); 288 + out: 289 + spi_finalize_current_transfer(master); 364 290 365 291 return status; 366 292 } ··· 304 374 mutex_unlock(&bitbang->lock); 305 375 306 376 return 0; 377 + } 378 + 379 + static void spi_bitbang_set_cs(struct spi_device *spi, bool enable) 380 + { 381 + struct spi_bitbang *bitbang = spi_master_get_devdata(spi->master); 382 + 383 + /* SPI core provides CS high / low, but bitbang driver 384 + * expects CS active 385 + * spi device driver takes care of handling SPI_CS_HIGH 386 + */ 387 + enable = (!!(spi->mode & SPI_CS_HIGH) == enable); 388 + 389 + ndelay(SPI_BITBANG_CS_DELAY); 390 + bitbang->chipselect(spi, enable ? BITBANG_CS_ACTIVE : 391 + BITBANG_CS_INACTIVE); 392 + ndelay(SPI_BITBANG_CS_DELAY); 307 393 } 308 394 309 395 /*----------------------------------------------------------------------*/ ··· 370 424 371 425 master->prepare_transfer_hardware = spi_bitbang_prepare_hardware; 372 426 master->unprepare_transfer_hardware = spi_bitbang_unprepare_hardware; 373 - master->transfer_one_message = spi_bitbang_transfer_one; 427 + master->transfer_one = spi_bitbang_transfer_one; 428 + master->set_cs = spi_bitbang_set_cs; 374 429 375 430 if (!bitbang->txrx_bufs) { 376 431 bitbang->use_dma = 0;