From e866878cd2a68e7ef46241f4317eddabb2eb359e Mon Sep 17 00:00:00 2001 From: Balaji Rao Date: Thu, 26 Feb 2009 04:10:52 +0000 Subject: Subject: lis302dl_use_s3c24xx_gpio_spi_bitbang.patch X-Git-Url: http://git.openmoko.org/?p=kernel.git;a=commitdiff_plain;h=5689ad9b0ded29adec4be64df53e488c648b9831 lis302dl_use_s3c24xx_gpio_spi_bitbang.patch Change lis302dl driver to use generic spi code. This requires that we define a s3c24xx_gpio spi bitbang based controller in mach-gta02.c. Signed-off-by: Balaji Rao --- drivers/input/misc/lis302dl.c | 102 ++++++++++++++++++++++++++++++++---------- 1 file changed, 78 insertions(+), 24 deletions(-) (limited to 'drivers/input/misc/lis302dl.c') diff --git a/drivers/input/misc/lis302dl.c b/drivers/input/misc/lis302dl.c index 3def0c41f8b..772c09c4a49 100644 --- a/drivers/input/misc/lis302dl.c +++ b/drivers/input/misc/lis302dl.c @@ -40,18 +40,51 @@ #include #include #include +#include #include /* Utility functions */ static u8 __reg_read(struct lis302dl_info *lis, u8 reg) { - return (lis->pdata->lis302dl_bitbang_reg_read)(lis, reg); + struct spi_message msg; + struct spi_transfer t; + u8 data[2] = {0xc0 | reg}; + int rc; + + spi_message_init(&msg); + memset(&t, 0, sizeof t); + t.len = 2; + spi_message_add_tail(&t, &msg); + t.tx_buf = &data[0]; + t.rx_buf = &data[0]; + + /* Should complete without blocking */ + rc = spi_non_blocking_transfer(lis->spi, &msg); + if (rc < 0) { + dev_err(lis->dev, "Error reading register\n"); + return rc; + } + + return data[1]; } static void __reg_write(struct lis302dl_info *lis, u8 reg, u8 val) -{ - (lis->pdata->lis302dl_bitbang_reg_write)(lis, reg, val); +{ + struct spi_message msg; + struct spi_transfer t; + u8 data[2] = {reg, val}; + + spi_message_init(&msg); + memset(&t, 0, sizeof t); + t.len = 2; + spi_message_add_tail(&t, &msg); + t.tx_buf = &data[0]; + t.rx_buf = &data[0]; + + /* Completes without blocking */ + if (spi_non_blocking_transfer(lis->spi, &msg) < 0) + dev_err(lis->dev, "Error writing register\n"); } static void __reg_set_bit_mask(struct lis302dl_info *lis, u8 reg, u8 mask, @@ -213,15 +246,28 @@ static void _report_btn_double(struct input_dev *inp, int btn) static void lis302dl_bitbang_read_sample(struct lis302dl_info *lis) { - u8 data = 0xc0 | LIS302DL_REG_STATUS; /* read, autoincrement */ - u8 read[(LIS302DL_REG_OUT_Z - LIS302DL_REG_STATUS) + 1]; + u8 data[(LIS302DL_REG_OUT_Z - LIS302DL_REG_STATUS) + 2] = {0xC0 | LIS302DL_REG_STATUS}; + u8 *read = data + 1; unsigned long flags; int mg_per_sample = __threshold_to_mg(lis, 1); + struct spi_message msg; + struct spi_transfer t; + + spi_message_init(&msg); + memset(&t, 0, sizeof t); + t.len = sizeof(data); + spi_message_add_tail(&t, &msg); + t.tx_buf = &data[0]; + t.rx_buf = &data[0]; /* grab the set of register containing status and XYZ data */ local_irq_save(flags); - (lis->pdata->lis302dl_bitbang)(lis, &data, 1, &read[0], sizeof(read)); + + /* Should complete without blocking */ + if (spi_non_blocking_transfer(lis->spi, &msg) < 0) + dev_err(lis->dev, "Error reading registers\n"); + local_irq_restore(flags); /* @@ -601,19 +647,27 @@ static int __lis302dl_reset_device(struct lis302dl_info *lis) return !!(timeout < 0); } -static int __devinit lis302dl_probe(struct platform_device *pdev) +static int __devinit lis302dl_probe(struct spi_device *spi) { int rc; struct lis302dl_info *lis; u_int8_t wai; unsigned long flags; - struct lis302dl_platform_data *pdata = pdev->dev.platform_data; + struct lis302dl_platform_data *pdata = spi->dev.platform_data; + + spi->mode = SPI_MODE_3; + rc = spi_setup(spi); + if (rc < 0) { + dev_err(&spi->dev, "spi_setup failed\n"); + return rc; + } lis = kzalloc(sizeof(*lis), GFP_KERNEL); if (!lis) return -ENOMEM; - lis->dev = &pdev->dev; + lis->dev = &spi->dev; + lis->spi = spi; dev_set_drvdata(lis->dev, lis); @@ -736,9 +790,9 @@ bail_free_lis: return rc; } -static int __devexit lis302dl_remove(struct platform_device *pdev) +static int __devexit lis302dl_remove(struct spi_device *spi) { - struct lis302dl_info *lis = dev_get_drvdata(&pdev->dev); + struct lis302dl_info *lis = dev_get_drvdata(&spi->dev); unsigned long flags; /* Disable interrupts */ @@ -754,7 +808,7 @@ static int __devexit lis302dl_remove(struct platform_device *pdev) local_irq_restore(flags); /* Cleanup resources */ - sysfs_remove_group(&pdev->dev.kobj, &lis302dl_attr_group); + sysfs_remove_group(&spi->dev.kobj, &lis302dl_attr_group); input_unregister_device(lis->input_dev); if (lis->input_dev) input_free_device(lis->input_dev); @@ -785,9 +839,9 @@ static u8 regs_to_save[] = { }; -static int lis302dl_suspend(struct platform_device *pdev, pm_message_t state) +static int lis302dl_suspend(struct spi_device *spi, pm_message_t state) { - struct lis302dl_info *lis = dev_get_drvdata(&pdev->dev); + struct lis302dl_info *lis = dev_get_drvdata(&spi->dev); unsigned long flags; u_int8_t tmp; int n; @@ -830,9 +884,9 @@ static int lis302dl_suspend(struct platform_device *pdev, pm_message_t state) return 0; } -static int lis302dl_resume(struct platform_device *pdev) +static int lis302dl_resume(struct spi_device *spi) { - struct lis302dl_info *lis = dev_get_drvdata(&pdev->dev); + struct lis302dl_info *lis = dev_get_drvdata(&spi->dev); unsigned long flags; int n; @@ -853,7 +907,7 @@ static int lis302dl_resume(struct platform_device *pdev) mdelay(1); if (__lis302dl_reset_device(lis)) - dev_err(&pdev->dev, "device BOOT reload failed\n"); + dev_err(&spi->dev, "device BOOT reload failed\n"); lis->regs[LIS302DL_REG_CTRL1] |= LIS302DL_CTRL1_PD | LIS302DL_CTRL1_Xen | @@ -878,26 +932,26 @@ static int lis302dl_resume(struct platform_device *pdev) #define lis302dl_resume NULL #endif -static struct platform_driver lis302dl_driver = { +static struct spi_driver lis302dl_spi_driver = { .driver = { - .name = "lis302dl", - .owner = THIS_MODULE, + .name = "lis302dl", + .owner = THIS_MODULE, }, - .probe = lis302dl_probe, - .remove = __devexit_p(lis302dl_remove), + .probe = lis302dl_probe, + .remove = __devexit_p(lis302dl_remove), .suspend = lis302dl_suspend, .resume = lis302dl_resume, }; static int __devinit lis302dl_init(void) { - return platform_driver_register(&lis302dl_driver); + return spi_register_driver(&lis302dl_spi_driver); } static void __exit lis302dl_exit(void) { - platform_driver_unregister(&lis302dl_driver); + spi_unregister_driver(&lis302dl_spi_driver); } MODULE_AUTHOR("Harald Welte "); -- cgit v1.2.3