X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fspi%2Fspi_s3c24xx.c;h=b3ebc1d0f85fc8ac93c4935eb793f8193d9e7682;hb=a963ea83b316b0a3ebf1c7118a6c36b5cd334bb6;hp=6f2c79da984dc01bb7b359f5ffb5a6a98ef5b7b0;hpb=4bb5eba06b4bc57e30b0f6336c9907e85c395197;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c index 6f2c79d..b3ebc1d 100644 --- a/drivers/spi/spi_s3c24xx.c +++ b/drivers/spi/spi_s3c24xx.c @@ -19,17 +19,17 @@ #include #include #include +#include #include #include #include #include -#include +#include -#include -#include -#include +#include +#include struct s3c24xx_spi { /* bitbang has to be first */ @@ -66,7 +66,7 @@ static inline struct s3c24xx_spi *to_hw(struct spi_device *sdev) static void s3c24xx_spi_gpiocs(struct s3c2410_spi_info *spi, int cs, int pol) { - s3c2410_gpio_setpin(spi->pin_cs, pol); + gpio_set_value(spi->pin_cs, pol); } static void s3c24xx_spi_chipsel(struct spi_device *spi, int value) @@ -125,10 +125,10 @@ static int s3c24xx_spi_setupxfer(struct spi_device *spi, /* is clk = pclk / (2 * (pre+1)), or is it * clk = (pclk * 2) / ( pre + 1) */ - div = (div / 2) - 1; + div /= 2; - if (div < 0) - div = 1; + if (div > 0) + div -= 1; if (div > 255) div = 255; @@ -169,7 +169,7 @@ static int s3c24xx_spi_setup(struct spi_device *spi) } dev_dbg(&spi->dev, "%s: mode %d, %u bpw, %d hz\n", - __FUNCTION__, spi->mode, spi->bits_per_word, + __func__, spi->mode, spi->bits_per_word, spi->max_speed_hz); return 0; @@ -236,8 +236,30 @@ static irqreturn_t s3c24xx_spi_irq(int irq, void *dev) return IRQ_HANDLED; } +static void s3c24xx_spi_initialsetup(struct s3c24xx_spi *hw) +{ + /* for the moment, permanently enable the clock */ + + clk_enable(hw->clk); + + /* program defaults into the registers */ + + writeb(0xff, hw->regs + S3C2410_SPPRE); + writeb(SPPIN_DEFAULT, hw->regs + S3C2410_SPPIN); + writeb(SPCON_DEFAULT, hw->regs + S3C2410_SPCON); + + if (hw->pdata) { + if (hw->set_cs == s3c24xx_spi_gpiocs) + gpio_direction_output(hw->pdata->pin_cs, 1); + + if (hw->pdata->gpio_setup) + hw->pdata->gpio_setup(hw->pdata, 1); + } +} + static int __init s3c24xx_spi_probe(struct platform_device *pdev) { + struct s3c2410_spi_info *pdata; struct s3c24xx_spi *hw; struct spi_master *master; struct resource *res; @@ -254,10 +276,10 @@ static int __init s3c24xx_spi_probe(struct platform_device *pdev) memset(hw, 0, sizeof(struct s3c24xx_spi)); hw->master = spi_master_get(master); - hw->pdata = pdev->dev.platform_data; + hw->pdata = pdata = pdev->dev.platform_data; hw->dev = &pdev->dev; - if (hw->pdata == NULL) { + if (pdata == NULL) { dev_err(&pdev->dev, "No platform data supplied\n"); err = -ENOENT; goto err_no_pdata; @@ -266,6 +288,11 @@ static int __init s3c24xx_spi_probe(struct platform_device *pdev) platform_set_drvdata(pdev, hw); init_completion(&hw->done); + /* setup the master state. */ + + master->num_chipselect = hw->pdata->num_cs; + master->bus_num = pdata->bus_num; + /* setup the state for the bitbang driver */ hw->bitbang.master = hw->master; @@ -321,25 +348,26 @@ static int __init s3c24xx_spi_probe(struct platform_device *pdev) goto err_no_clk; } - /* for the moment, permanently enable the clock */ + /* setup any gpio we can */ - clk_enable(hw->clk); + if (!pdata->set_cs) { + if (pdata->pin_cs < 0) { + dev_err(&pdev->dev, "No chipselect pin\n"); + goto err_register; + } - /* program defaults into the registers */ - - writeb(0xff, hw->regs + S3C2410_SPPRE); - writeb(SPPIN_DEFAULT, hw->regs + S3C2410_SPPIN); - writeb(SPCON_DEFAULT, hw->regs + S3C2410_SPCON); + err = gpio_request(pdata->pin_cs, dev_name(&pdev->dev)); + if (err) { + dev_err(&pdev->dev, "Failed to get gpio for cs\n"); + goto err_register; + } - /* setup any gpio we can */ - - if (!hw->pdata->set_cs) { hw->set_cs = s3c24xx_spi_gpiocs; - - s3c2410_gpio_setpin(hw->pdata->pin_cs, 1); - s3c2410_gpio_cfgpin(hw->pdata->pin_cs, S3C2410_GPIO_OUTPUT); + gpio_direction_output(pdata->pin_cs, 1); } else - hw->set_cs = hw->pdata->set_cs; + hw->set_cs = pdata->set_cs; + + s3c24xx_spi_initialsetup(hw); /* register our spi controller */ @@ -352,6 +380,9 @@ static int __init s3c24xx_spi_probe(struct platform_device *pdev) return 0; err_register: + if (hw->set_cs == s3c24xx_spi_gpiocs) + gpio_free(pdata->pin_cs); + clk_disable(hw->clk); clk_put(hw->clk); @@ -387,6 +418,9 @@ static int __exit s3c24xx_spi_remove(struct platform_device *dev) free_irq(hw->irq, hw); iounmap(hw->regs); + if (hw->set_cs == s3c24xx_spi_gpiocs) + gpio_free(hw->pdata->pin_cs); + release_resource(hw->ioarea); kfree(hw->ioarea); @@ -401,6 +435,9 @@ static int s3c24xx_spi_suspend(struct platform_device *pdev, pm_message_t msg) { struct s3c24xx_spi *hw = platform_get_drvdata(pdev); + if (hw->pdata && hw->pdata->gpio_setup) + hw->pdata->gpio_setup(hw->pdata, 0); + clk_disable(hw->clk); return 0; } @@ -409,7 +446,7 @@ static int s3c24xx_spi_resume(struct platform_device *pdev) { struct s3c24xx_spi *hw = platform_get_drvdata(pdev); - clk_enable(hw->clk); + s3c24xx_spi_initialsetup(hw); return 0; } @@ -419,7 +456,7 @@ static int s3c24xx_spi_resume(struct platform_device *pdev) #endif MODULE_ALIAS("platform:s3c2410-spi"); -static struct platform_driver s3c24xx_spidrv = { +static struct platform_driver s3c24xx_spi_driver = { .remove = __exit_p(s3c24xx_spi_remove), .suspend = s3c24xx_spi_suspend, .resume = s3c24xx_spi_resume, @@ -431,12 +468,12 @@ static struct platform_driver s3c24xx_spidrv = { static int __init s3c24xx_spi_init(void) { - return platform_driver_probe(&s3c24xx_spidrv, s3c24xx_spi_probe); + return platform_driver_probe(&s3c24xx_spi_driver, s3c24xx_spi_probe); } static void __exit s3c24xx_spi_exit(void) { - platform_driver_unregister(&s3c24xx_spidrv); + platform_driver_unregister(&s3c24xx_spi_driver); } module_init(s3c24xx_spi_init);