131a62963SBryan Wu /* 231a62963SBryan Wu * AD714X CapTouch Programmable Controller driver (SPI bus) 331a62963SBryan Wu * 431a62963SBryan Wu * Copyright 2009 Analog Devices Inc. 531a62963SBryan Wu * 631a62963SBryan Wu * Licensed under the GPL-2 or later. 731a62963SBryan Wu */ 831a62963SBryan Wu 931a62963SBryan Wu #include <linux/input.h> /* BUS_I2C */ 1031a62963SBryan Wu #include <linux/module.h> 1131a62963SBryan Wu #include <linux/spi/spi.h> 12a257090cSMark Brown #include <linux/pm.h> 1331a62963SBryan Wu #include <linux/types.h> 1431a62963SBryan Wu #include "ad714x.h" 1531a62963SBryan Wu 1631a62963SBryan Wu #define AD714x_SPI_CMD_PREFIX 0xE000 /* bits 15:11 */ 1731a62963SBryan Wu #define AD714x_SPI_READ BIT(10) 1831a62963SBryan Wu 1931a62963SBryan Wu #ifdef CONFIG_PM 20a257090cSMark Brown static int ad714x_spi_suspend(struct device *dev) 2131a62963SBryan Wu { 22a257090cSMark Brown return ad714x_disable(spi_get_drvdata(to_spi_device(dev))); 2331a62963SBryan Wu } 2431a62963SBryan Wu 25a257090cSMark Brown static int ad714x_spi_resume(struct device *dev) 2631a62963SBryan Wu { 27a257090cSMark Brown return ad714x_enable(spi_get_drvdata(to_spi_device(dev))); 2831a62963SBryan Wu } 2931a62963SBryan Wu #endif 3031a62963SBryan Wu 31a257090cSMark Brown static SIMPLE_DEV_PM_OPS(ad714x_spi_pm, ad714x_spi_suspend, ad714x_spi_resume); 32a257090cSMark Brown 3331a62963SBryan Wu static int ad714x_spi_read(struct device *dev, unsigned short reg, 3431a62963SBryan Wu unsigned short *data) 3531a62963SBryan Wu { 3631a62963SBryan Wu struct spi_device *spi = to_spi_device(dev); 3731a62963SBryan Wu unsigned short tx = AD714x_SPI_CMD_PREFIX | AD714x_SPI_READ | reg; 3831a62963SBryan Wu 3931a62963SBryan Wu return spi_write_then_read(spi, (u8 *)&tx, 2, (u8 *)data, 2); 4031a62963SBryan Wu } 4131a62963SBryan Wu 4231a62963SBryan Wu static int ad714x_spi_write(struct device *dev, unsigned short reg, 4331a62963SBryan Wu unsigned short data) 4431a62963SBryan Wu { 4531a62963SBryan Wu struct spi_device *spi = to_spi_device(dev); 4631a62963SBryan Wu unsigned short tx[2] = { 4731a62963SBryan Wu AD714x_SPI_CMD_PREFIX | reg, 4831a62963SBryan Wu data 4931a62963SBryan Wu }; 5031a62963SBryan Wu 5131a62963SBryan Wu return spi_write(spi, (u8 *)tx, 4); 5231a62963SBryan Wu } 5331a62963SBryan Wu 5431a62963SBryan Wu static int __devinit ad714x_spi_probe(struct spi_device *spi) 5531a62963SBryan Wu { 5631a62963SBryan Wu struct ad714x_chip *chip; 57*5b9063b1SMichael Hennerich int err; 58*5b9063b1SMichael Hennerich 59*5b9063b1SMichael Hennerich spi->bits_per_word = 8; 60*5b9063b1SMichael Hennerich err = spi_setup(spi); 61*5b9063b1SMichael Hennerich if (err < 0) 62*5b9063b1SMichael Hennerich return err; 6331a62963SBryan Wu 6431a62963SBryan Wu chip = ad714x_probe(&spi->dev, BUS_SPI, spi->irq, 6531a62963SBryan Wu ad714x_spi_read, ad714x_spi_write); 6631a62963SBryan Wu if (IS_ERR(chip)) 6731a62963SBryan Wu return PTR_ERR(chip); 6831a62963SBryan Wu 6931a62963SBryan Wu spi_set_drvdata(spi, chip); 7031a62963SBryan Wu 7131a62963SBryan Wu return 0; 7231a62963SBryan Wu } 7331a62963SBryan Wu 7431a62963SBryan Wu static int __devexit ad714x_spi_remove(struct spi_device *spi) 7531a62963SBryan Wu { 7631a62963SBryan Wu struct ad714x_chip *chip = spi_get_drvdata(spi); 7731a62963SBryan Wu 7831a62963SBryan Wu ad714x_remove(chip); 7931a62963SBryan Wu spi_set_drvdata(spi, NULL); 8031a62963SBryan Wu 8131a62963SBryan Wu return 0; 8231a62963SBryan Wu } 8331a62963SBryan Wu 8431a62963SBryan Wu static struct spi_driver ad714x_spi_driver = { 8531a62963SBryan Wu .driver = { 8631a62963SBryan Wu .name = "ad714x_captouch", 8731a62963SBryan Wu .owner = THIS_MODULE, 88a257090cSMark Brown .pm = &ad714x_spi_pm, 8931a62963SBryan Wu }, 9031a62963SBryan Wu .probe = ad714x_spi_probe, 9131a62963SBryan Wu .remove = __devexit_p(ad714x_spi_remove), 9231a62963SBryan Wu }; 9331a62963SBryan Wu 9431a62963SBryan Wu static __init int ad714x_spi_init(void) 9531a62963SBryan Wu { 9631a62963SBryan Wu return spi_register_driver(&ad714x_spi_driver); 9731a62963SBryan Wu } 9831a62963SBryan Wu module_init(ad714x_spi_init); 9931a62963SBryan Wu 10031a62963SBryan Wu static __exit void ad714x_spi_exit(void) 10131a62963SBryan Wu { 10231a62963SBryan Wu spi_unregister_driver(&ad714x_spi_driver); 10331a62963SBryan Wu } 10431a62963SBryan Wu module_exit(ad714x_spi_exit); 10531a62963SBryan Wu 10631a62963SBryan Wu MODULE_DESCRIPTION("Analog Devices AD714X Capacitance Touch Sensor SPI Bus Driver"); 10731a62963SBryan Wu MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); 10831a62963SBryan Wu MODULE_LICENSE("GPL"); 109