Lines Matching +full:cs +full:- +full:gpio
3 * Copyright 2006-2009 Simtec Electronics
21 #include <linux/gpio.h>
29 #include <plat/regs-spi.h>
35 #include "spi-s3c24xx-fiq.h"
38 * s3c24xx_spi_devstate - per device data
74 int cs, int pol);
94 return spi_master_get_devdata(sdev->master); in to_hw()
97 static void s3c24xx_spi_gpiocs(struct s3c2410_spi_info *spi, int cs, int pol) in s3c24xx_spi_gpiocs() argument
99 gpio_set_value(spi->pin_cs, pol); in s3c24xx_spi_gpiocs()
104 struct s3c24xx_spi_devstate *cs = spi->controller_state; in s3c24xx_spi_chipsel() local
106 unsigned int cspol = spi->mode & SPI_CS_HIGH ? 1 : 0; in s3c24xx_spi_chipsel()
112 hw->set_cs(hw->pdata, spi->chip_select, cspol^1); in s3c24xx_spi_chipsel()
113 writeb(cs->spcon, hw->regs + S3C2410_SPCON); in s3c24xx_spi_chipsel()
117 writeb(cs->spcon | S3C2410_SPCON_ENSCK, in s3c24xx_spi_chipsel()
118 hw->regs + S3C2410_SPCON); in s3c24xx_spi_chipsel()
119 hw->set_cs(hw->pdata, spi->chip_select, cspol); in s3c24xx_spi_chipsel()
128 struct s3c24xx_spi_devstate *cs = spi->controller_state; in s3c24xx_spi_update_state() local
134 bpw = t ? t->bits_per_word : spi->bits_per_word; in s3c24xx_spi_update_state()
135 hz = t ? t->speed_hz : spi->max_speed_hz; in s3c24xx_spi_update_state()
141 hz = spi->max_speed_hz; in s3c24xx_spi_update_state()
144 dev_err(&spi->dev, "invalid bits-per-word (%d)\n", bpw); in s3c24xx_spi_update_state()
145 return -EINVAL; in s3c24xx_spi_update_state()
148 if (spi->mode != cs->mode) { in s3c24xx_spi_update_state()
151 if (spi->mode & SPI_CPHA) in s3c24xx_spi_update_state()
154 if (spi->mode & SPI_CPOL) in s3c24xx_spi_update_state()
157 cs->mode = spi->mode; in s3c24xx_spi_update_state()
158 cs->spcon = spcon; in s3c24xx_spi_update_state()
161 if (cs->hz != hz) { in s3c24xx_spi_update_state()
162 clk = clk_get_rate(hw->clk); in s3c24xx_spi_update_state()
163 div = DIV_ROUND_UP(clk, hz * 2) - 1; in s3c24xx_spi_update_state()
168 dev_dbg(&spi->dev, "pre-scaler=%d (wanted %d, got %ld)\n", in s3c24xx_spi_update_state()
171 cs->hz = hz; in s3c24xx_spi_update_state()
172 cs->sppre = div; in s3c24xx_spi_update_state()
181 struct s3c24xx_spi_devstate *cs = spi->controller_state; in s3c24xx_spi_setupxfer() local
187 writeb(cs->sppre, hw->regs + S3C2410_SPPRE); in s3c24xx_spi_setupxfer()
194 struct s3c24xx_spi_devstate *cs = spi->controller_state; in s3c24xx_spi_setup() local
199 if (!cs) { in s3c24xx_spi_setup()
200 cs = kzalloc(sizeof(struct s3c24xx_spi_devstate), GFP_KERNEL); in s3c24xx_spi_setup()
201 if (!cs) { in s3c24xx_spi_setup()
202 dev_err(&spi->dev, "no memory for controller state\n"); in s3c24xx_spi_setup()
203 return -ENOMEM; in s3c24xx_spi_setup()
206 cs->spcon = SPCON_DEFAULT; in s3c24xx_spi_setup()
207 cs->hz = -1; in s3c24xx_spi_setup()
208 spi->controller_state = cs; in s3c24xx_spi_setup()
216 spin_lock(&hw->bitbang.lock); in s3c24xx_spi_setup()
217 if (!hw->bitbang.busy) { in s3c24xx_spi_setup()
218 hw->bitbang.chipselect(spi, BITBANG_CS_INACTIVE); in s3c24xx_spi_setup()
221 spin_unlock(&hw->bitbang.lock); in s3c24xx_spi_setup()
228 kfree(spi->controller_state); in s3c24xx_spi_cleanup()
233 return hw->tx ? hw->tx[count] : 0; in hw_txbyte()
237 /* Support for FIQ based pseudo-DMA to improve the transfer speed.
246 * struct spi_fiq_code - FIQ code and header
262 * ack_bit - turn IRQ into IRQ acknowledgement bit
269 return 1 << (irq - IRQ_EINT0); in ack_bit()
273 * s3c24xx_spi_tryfiq - attempt to claim and setup FIQ for transfer
281 * as normal, since the IRQ will have been re-routed to the FIQ handler.
290 if (!hw->fiq_claimed) { in s3c24xx_spi_tryfiq()
294 ret = claim_fiq(&hw->fiq_handler); in s3c24xx_spi_tryfiq()
299 if (hw->tx && !hw->rx) in s3c24xx_spi_tryfiq()
301 else if (hw->rx && !hw->tx) in s3c24xx_spi_tryfiq()
306 regs.uregs[fiq_rspi] = (long)hw->regs; in s3c24xx_spi_tryfiq()
307 regs.uregs[fiq_rrx] = (long)hw->rx; in s3c24xx_spi_tryfiq()
308 regs.uregs[fiq_rtx] = (long)hw->tx + 1; in s3c24xx_spi_tryfiq()
309 regs.uregs[fiq_rcount] = hw->len - 1; in s3c24xx_spi_tryfiq()
314 if (hw->fiq_mode != mode) { in s3c24xx_spi_tryfiq()
317 hw->fiq_mode = mode; in s3c24xx_spi_tryfiq()
335 ack_ptr = (u32 *)&code->data[code->ack_offset]; in s3c24xx_spi_tryfiq()
336 *ack_ptr = ack_bit(hw->irq); in s3c24xx_spi_tryfiq()
338 set_fiq_handler(&code->data, code->length); in s3c24xx_spi_tryfiq()
341 s3c24xx_set_fiq(hw->irq, true); in s3c24xx_spi_tryfiq()
343 hw->fiq_mode = mode; in s3c24xx_spi_tryfiq()
344 hw->fiq_inuse = 1; in s3c24xx_spi_tryfiq()
348 * s3c24xx_spi_fiqop - FIQ core code callback
362 if (hw->fiq_inuse) in s3c24xx_spi_fiqop()
363 ret = -EBUSY; in s3c24xx_spi_fiqop()
366 * vector code de-routes it to signal the end of transfer */ in s3c24xx_spi_fiqop()
368 hw->fiq_mode = FIQ_MODE_NONE; in s3c24xx_spi_fiqop()
369 hw->fiq_claimed = 0; in s3c24xx_spi_fiqop()
371 hw->fiq_claimed = 1; in s3c24xx_spi_fiqop()
378 * s3c24xx_spi_initfiq - setup the information for the FIQ core
385 hw->fiq_handler.dev_id = hw; in s3c24xx_spi_initfiq()
386 hw->fiq_handler.name = dev_name(hw->dev); in s3c24xx_spi_initfiq()
387 hw->fiq_handler.fiq_op = s3c24xx_spi_fiqop; in s3c24xx_spi_initfiq()
391 * s3c24xx_spi_usefiq - return if we should be using FIQ.
399 return hw->pdata->use_fiq; in s3c24xx_spi_usefiq()
403 * s3c24xx_spi_usingfiq - return if channel is using FIQ
411 return spi->fiq_inuse; in s3c24xx_spi_usingfiq()
426 hw->tx = t->tx_buf; in s3c24xx_spi_txrx()
427 hw->rx = t->rx_buf; in s3c24xx_spi_txrx()
428 hw->len = t->len; in s3c24xx_spi_txrx()
429 hw->count = 0; in s3c24xx_spi_txrx()
431 init_completion(&hw->done); in s3c24xx_spi_txrx()
433 hw->fiq_inuse = 0; in s3c24xx_spi_txrx()
434 if (s3c24xx_spi_usefiq(hw) && t->len >= 3) in s3c24xx_spi_txrx()
438 writeb(hw_txbyte(hw, 0), hw->regs + S3C2410_SPTDAT); in s3c24xx_spi_txrx()
440 wait_for_completion(&hw->done); in s3c24xx_spi_txrx()
441 return hw->count; in s3c24xx_spi_txrx()
447 unsigned int spsta = readb(hw->regs + S3C2410_SPSTA); in s3c24xx_spi_irq()
448 unsigned int count = hw->count; in s3c24xx_spi_irq()
451 dev_dbg(hw->dev, "data-collision\n"); in s3c24xx_spi_irq()
452 complete(&hw->done); in s3c24xx_spi_irq()
457 dev_dbg(hw->dev, "spi not ready for tx?\n"); in s3c24xx_spi_irq()
458 complete(&hw->done); in s3c24xx_spi_irq()
463 hw->count++; in s3c24xx_spi_irq()
465 if (hw->rx) in s3c24xx_spi_irq()
466 hw->rx[count] = readb(hw->regs + S3C2410_SPRDAT); in s3c24xx_spi_irq()
470 if (count < hw->len) in s3c24xx_spi_irq()
471 writeb(hw_txbyte(hw, count), hw->regs + S3C2410_SPTDAT); in s3c24xx_spi_irq()
473 complete(&hw->done); in s3c24xx_spi_irq()
475 hw->count = hw->len; in s3c24xx_spi_irq()
476 hw->fiq_inuse = 0; in s3c24xx_spi_irq()
478 if (hw->rx) in s3c24xx_spi_irq()
479 hw->rx[hw->len-1] = readb(hw->regs + S3C2410_SPRDAT); in s3c24xx_spi_irq()
481 complete(&hw->done); in s3c24xx_spi_irq()
492 clk_enable(hw->clk); in s3c24xx_spi_initialsetup()
496 writeb(0xff, hw->regs + S3C2410_SPPRE); in s3c24xx_spi_initialsetup()
497 writeb(SPPIN_DEFAULT, hw->regs + S3C2410_SPPIN); in s3c24xx_spi_initialsetup()
498 writeb(SPCON_DEFAULT, hw->regs + S3C2410_SPCON); in s3c24xx_spi_initialsetup()
500 if (hw->pdata) { in s3c24xx_spi_initialsetup()
501 if (hw->set_cs == s3c24xx_spi_gpiocs) in s3c24xx_spi_initialsetup()
502 gpio_direction_output(hw->pdata->pin_cs, 1); in s3c24xx_spi_initialsetup()
504 if (hw->pdata->gpio_setup) in s3c24xx_spi_initialsetup()
505 hw->pdata->gpio_setup(hw->pdata, 1); in s3c24xx_spi_initialsetup()
517 master = spi_alloc_master(&pdev->dev, sizeof(struct s3c24xx_spi)); in s3c24xx_spi_probe()
519 dev_err(&pdev->dev, "No memory for spi_master\n"); in s3c24xx_spi_probe()
520 err = -ENOMEM; in s3c24xx_spi_probe()
527 hw->master = spi_master_get(master); in s3c24xx_spi_probe()
528 hw->pdata = pdata = pdev->dev.platform_data; in s3c24xx_spi_probe()
529 hw->dev = &pdev->dev; in s3c24xx_spi_probe()
532 dev_err(&pdev->dev, "No platform data supplied\n"); in s3c24xx_spi_probe()
533 err = -ENOENT; in s3c24xx_spi_probe()
538 init_completion(&hw->done); in s3c24xx_spi_probe()
546 /* the spi->mode bits understood by this driver: */ in s3c24xx_spi_probe()
547 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; in s3c24xx_spi_probe()
549 master->num_chipselect = hw->pdata->num_cs; in s3c24xx_spi_probe()
550 master->bus_num = pdata->bus_num; in s3c24xx_spi_probe()
554 hw->bitbang.master = hw->master; in s3c24xx_spi_probe()
555 hw->bitbang.setup_transfer = s3c24xx_spi_setupxfer; in s3c24xx_spi_probe()
556 hw->bitbang.chipselect = s3c24xx_spi_chipsel; in s3c24xx_spi_probe()
557 hw->bitbang.txrx_bufs = s3c24xx_spi_txrx; in s3c24xx_spi_probe()
559 hw->master->setup = s3c24xx_spi_setup; in s3c24xx_spi_probe()
560 hw->master->cleanup = s3c24xx_spi_cleanup; in s3c24xx_spi_probe()
562 dev_dbg(hw->dev, "bitbang at %p\n", &hw->bitbang); in s3c24xx_spi_probe()
568 dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n"); in s3c24xx_spi_probe()
569 err = -ENOENT; in s3c24xx_spi_probe()
573 hw->ioarea = request_mem_region(res->start, resource_size(res), in s3c24xx_spi_probe()
574 pdev->name); in s3c24xx_spi_probe()
576 if (hw->ioarea == NULL) { in s3c24xx_spi_probe()
577 dev_err(&pdev->dev, "Cannot reserve region\n"); in s3c24xx_spi_probe()
578 err = -ENXIO; in s3c24xx_spi_probe()
582 hw->regs = ioremap(res->start, resource_size(res)); in s3c24xx_spi_probe()
583 if (hw->regs == NULL) { in s3c24xx_spi_probe()
584 dev_err(&pdev->dev, "Cannot map IO\n"); in s3c24xx_spi_probe()
585 err = -ENXIO; in s3c24xx_spi_probe()
589 hw->irq = platform_get_irq(pdev, 0); in s3c24xx_spi_probe()
590 if (hw->irq < 0) { in s3c24xx_spi_probe()
591 dev_err(&pdev->dev, "No IRQ specified\n"); in s3c24xx_spi_probe()
592 err = -ENOENT; in s3c24xx_spi_probe()
596 err = request_irq(hw->irq, s3c24xx_spi_irq, 0, pdev->name, hw); in s3c24xx_spi_probe()
598 dev_err(&pdev->dev, "Cannot claim IRQ\n"); in s3c24xx_spi_probe()
602 hw->clk = clk_get(&pdev->dev, "spi"); in s3c24xx_spi_probe()
603 if (IS_ERR(hw->clk)) { in s3c24xx_spi_probe()
604 dev_err(&pdev->dev, "No clock for device\n"); in s3c24xx_spi_probe()
605 err = PTR_ERR(hw->clk); in s3c24xx_spi_probe()
609 /* setup any gpio we can */ in s3c24xx_spi_probe()
611 if (!pdata->set_cs) { in s3c24xx_spi_probe()
612 if (pdata->pin_cs < 0) { in s3c24xx_spi_probe()
613 dev_err(&pdev->dev, "No chipselect pin\n"); in s3c24xx_spi_probe()
617 err = gpio_request(pdata->pin_cs, dev_name(&pdev->dev)); in s3c24xx_spi_probe()
619 dev_err(&pdev->dev, "Failed to get gpio for cs\n"); in s3c24xx_spi_probe()
623 hw->set_cs = s3c24xx_spi_gpiocs; in s3c24xx_spi_probe()
624 gpio_direction_output(pdata->pin_cs, 1); in s3c24xx_spi_probe()
626 hw->set_cs = pdata->set_cs; in s3c24xx_spi_probe()
632 err = spi_bitbang_start(&hw->bitbang); in s3c24xx_spi_probe()
634 dev_err(&pdev->dev, "Failed to register SPI master\n"); in s3c24xx_spi_probe()
641 if (hw->set_cs == s3c24xx_spi_gpiocs) in s3c24xx_spi_probe()
642 gpio_free(pdata->pin_cs); in s3c24xx_spi_probe()
644 clk_disable(hw->clk); in s3c24xx_spi_probe()
645 clk_put(hw->clk); in s3c24xx_spi_probe()
648 free_irq(hw->irq, hw); in s3c24xx_spi_probe()
651 iounmap(hw->regs); in s3c24xx_spi_probe()
654 release_resource(hw->ioarea); in s3c24xx_spi_probe()
655 kfree(hw->ioarea); in s3c24xx_spi_probe()
659 spi_master_put(hw->master); in s3c24xx_spi_probe()
671 spi_bitbang_stop(&hw->bitbang); in s3c24xx_spi_remove()
673 clk_disable(hw->clk); in s3c24xx_spi_remove()
674 clk_put(hw->clk); in s3c24xx_spi_remove()
676 free_irq(hw->irq, hw); in s3c24xx_spi_remove()
677 iounmap(hw->regs); in s3c24xx_spi_remove()
679 if (hw->set_cs == s3c24xx_spi_gpiocs) in s3c24xx_spi_remove()
680 gpio_free(hw->pdata->pin_cs); in s3c24xx_spi_remove()
682 release_resource(hw->ioarea); in s3c24xx_spi_remove()
683 kfree(hw->ioarea); in s3c24xx_spi_remove()
685 spi_master_put(hw->master); in s3c24xx_spi_remove()
696 if (hw->pdata && hw->pdata->gpio_setup) in s3c24xx_spi_suspend()
697 hw->pdata->gpio_setup(hw->pdata, 0); in s3c24xx_spi_suspend()
699 clk_disable(hw->clk); in s3c24xx_spi_suspend()
721 MODULE_ALIAS("platform:s3c2410-spi");
726 .name = "s3c2410-spi",