14397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger/* 24397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger * AD7879-1/AD7889-1 touchscreen (I2C bus) 34397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger * 44397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger * Copyright (C) 2008-2010 Michael Hennerich, Analog Devices Inc. 54397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger * 64397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger * Licensed under the GPL-2 or later. 74397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger */ 84397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger 94397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger#include <linux/input.h> /* BUS_I2C */ 104397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger#include <linux/i2c.h> 114397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger#include <linux/module.h> 124397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger#include <linux/types.h> 13d5dc9ac3f6daf7df45c49e5a861c733a5f794c6bMark Brown#include <linux/pm.h> 144397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger 154397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger#include "ad7879.h" 164397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger 174397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger#define AD7879_DEVID 0x79 /* AD7879-1/AD7889-1 */ 184397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger 194397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger/* All registers are word-sized. 204397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger * AD7879 uses a high-byte first convention. 214397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger */ 224397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysingerstatic int ad7879_i2c_read(struct device *dev, u8 reg) 234397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger{ 244397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger struct i2c_client *client = to_i2c_client(dev); 254397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger 2675255b29d473613e2a5737d6fb368dc4009c90a8Jonathan Cameron return i2c_smbus_read_word_swapped(client, reg); 274397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger} 284397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger 294397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysingerstatic int ad7879_i2c_multi_read(struct device *dev, 304397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger u8 first_reg, u8 count, u16 *buf) 314397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger{ 3216ea10a7d557a0177cbbd716b4a06e5373d513baMichael Hennerich struct i2c_client *client = to_i2c_client(dev); 334397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger u8 idx; 344397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger 3516ea10a7d557a0177cbbd716b4a06e5373d513baMichael Hennerich i2c_smbus_read_i2c_block_data(client, first_reg, count * 2, (u8 *)buf); 3616ea10a7d557a0177cbbd716b4a06e5373d513baMichael Hennerich 374397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger for (idx = 0; idx < count; ++idx) 3816ea10a7d557a0177cbbd716b4a06e5373d513baMichael Hennerich buf[idx] = swab16(buf[idx]); 394397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger 404397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger return 0; 414397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger} 424397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger 434397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysingerstatic int ad7879_i2c_write(struct device *dev, u8 reg, u16 val) 444397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger{ 454397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger struct i2c_client *client = to_i2c_client(dev); 464397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger 4775255b29d473613e2a5737d6fb368dc4009c90a8Jonathan Cameron return i2c_smbus_write_word_swapped(client, reg, val); 484397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger} 494397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger 504397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysingerstatic const struct ad7879_bus_ops ad7879_i2c_bus_ops = { 514397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger .bustype = BUS_I2C, 524397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger .read = ad7879_i2c_read, 534397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger .multi_read = ad7879_i2c_multi_read, 544397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger .write = ad7879_i2c_write, 554397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger}; 564397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger 574397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysingerstatic int __devinit ad7879_i2c_probe(struct i2c_client *client, 584397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger const struct i2c_device_id *id) 594397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger{ 604397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger struct ad7879 *ts; 614397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger 624397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger if (!i2c_check_functionality(client->adapter, 634397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger I2C_FUNC_SMBUS_WORD_DATA)) { 644397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger dev_err(&client->dev, "SMBUS Word Data not Supported\n"); 654397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger return -EIO; 664397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger } 674397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger 684397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger ts = ad7879_probe(&client->dev, AD7879_DEVID, client->irq, 694397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger &ad7879_i2c_bus_ops); 704397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger if (IS_ERR(ts)) 714397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger return PTR_ERR(ts); 724397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger 734397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger i2c_set_clientdata(client, ts); 744397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger 754397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger return 0; 764397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger} 774397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger 784397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysingerstatic int __devexit ad7879_i2c_remove(struct i2c_client *client) 794397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger{ 804397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger struct ad7879 *ts = i2c_get_clientdata(client); 814397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger 824397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger ad7879_remove(ts); 834397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger 844397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger return 0; 854397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger} 864397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger 874397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysingerstatic const struct i2c_device_id ad7879_id[] = { 884397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger { "ad7879", 0 }, 894397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger { "ad7889", 0 }, 904397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger { } 914397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger}; 924397c98a8a60ba029f2d0051d0cbafe600f05d8cMike FrysingerMODULE_DEVICE_TABLE(i2c, ad7879_id); 934397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger 944397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysingerstatic struct i2c_driver ad7879_i2c_driver = { 954397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger .driver = { 964397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger .name = "ad7879", 974397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger .owner = THIS_MODULE, 988672bd93d3d67b18a2b067ece30dabcda11f8cdeDmitry Torokhov .pm = &ad7879_pm_ops, 994397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger }, 1004397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger .probe = ad7879_i2c_probe, 1014397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger .remove = __devexit_p(ad7879_i2c_remove), 1024397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger .id_table = ad7879_id, 1034397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger}; 1044397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger 1051b92c1cf6b638e7cbe9fdaac3f6efb8874f5cc02Axel Linmodule_i2c_driver(ad7879_i2c_driver); 1064397c98a8a60ba029f2d0051d0cbafe600f05d8cMike Frysinger 1074397c98a8a60ba029f2d0051d0cbafe600f05d8cMike FrysingerMODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); 1084397c98a8a60ba029f2d0051d0cbafe600f05d8cMike FrysingerMODULE_DESCRIPTION("AD7879(-1) touchscreen I2C bus driver"); 1094397c98a8a60ba029f2d0051d0cbafe600f05d8cMike FrysingerMODULE_LICENSE("GPL"); 110