1*cc7feb7fSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2dd4cae8bSChristian Gmeiner /* 3021cbc1eSMartin Kepplinger * Microchip AR1020 and AR1021 driver for I2C 4dd4cae8bSChristian Gmeiner * 5dd4cae8bSChristian Gmeiner * Author: Christian Gmeiner <christian.gmeiner@gmail.com> 6dd4cae8bSChristian Gmeiner */ 7dd4cae8bSChristian Gmeiner 88a038b83SMartin Kepplinger #include <linux/bitops.h> 9dd4cae8bSChristian Gmeiner #include <linux/module.h> 10dd4cae8bSChristian Gmeiner #include <linux/input.h> 11dd4cae8bSChristian Gmeiner #include <linux/of.h> 12dd4cae8bSChristian Gmeiner #include <linux/i2c.h> 13dd4cae8bSChristian Gmeiner #include <linux/irq.h> 14dd4cae8bSChristian Gmeiner #include <linux/interrupt.h> 15dd4cae8bSChristian Gmeiner 16dd4cae8bSChristian Gmeiner #define AR1021_TOCUH_PKG_SIZE 5 17dd4cae8bSChristian Gmeiner 18dd4cae8bSChristian Gmeiner #define AR1021_MAX_X 4095 19dd4cae8bSChristian Gmeiner #define AR1021_MAX_Y 4095 20dd4cae8bSChristian Gmeiner 21e55057e8SMartin Kepplinger #define AR1021_CMD 0x55 22e55057e8SMartin Kepplinger 23e55057e8SMartin Kepplinger #define AR1021_CMD_ENABLE_TOUCH 0x12 24e55057e8SMartin Kepplinger 25dd4cae8bSChristian Gmeiner struct ar1021_i2c { 26dd4cae8bSChristian Gmeiner struct i2c_client *client; 27dd4cae8bSChristian Gmeiner struct input_dev *input; 28dd4cae8bSChristian Gmeiner u8 data[AR1021_TOCUH_PKG_SIZE]; 29dd4cae8bSChristian Gmeiner }; 30dd4cae8bSChristian Gmeiner 31dd4cae8bSChristian Gmeiner static irqreturn_t ar1021_i2c_irq(int irq, void *dev_id) 32dd4cae8bSChristian Gmeiner { 33dd4cae8bSChristian Gmeiner struct ar1021_i2c *ar1021 = dev_id; 34dd4cae8bSChristian Gmeiner struct input_dev *input = ar1021->input; 35dd4cae8bSChristian Gmeiner u8 *data = ar1021->data; 36dd4cae8bSChristian Gmeiner unsigned int x, y, button; 37dd4cae8bSChristian Gmeiner int retval; 38dd4cae8bSChristian Gmeiner 39dd4cae8bSChristian Gmeiner retval = i2c_master_recv(ar1021->client, 40dd4cae8bSChristian Gmeiner ar1021->data, sizeof(ar1021->data)); 41dd4cae8bSChristian Gmeiner if (retval != sizeof(ar1021->data)) 42dd4cae8bSChristian Gmeiner goto out; 43dd4cae8bSChristian Gmeiner 44dd4cae8bSChristian Gmeiner /* sync bit set ? */ 458a038b83SMartin Kepplinger if (!(data[0] & BIT(7))) 46dd4cae8bSChristian Gmeiner goto out; 47dd4cae8bSChristian Gmeiner 48dd4cae8bSChristian Gmeiner button = data[0] & BIT(0); 49dd4cae8bSChristian Gmeiner x = ((data[2] & 0x1f) << 7) | (data[1] & 0x7f); 50dd4cae8bSChristian Gmeiner y = ((data[4] & 0x1f) << 7) | (data[3] & 0x7f); 51dd4cae8bSChristian Gmeiner 52dd4cae8bSChristian Gmeiner input_report_abs(input, ABS_X, x); 53dd4cae8bSChristian Gmeiner input_report_abs(input, ABS_Y, y); 54dd4cae8bSChristian Gmeiner input_report_key(input, BTN_TOUCH, button); 55dd4cae8bSChristian Gmeiner input_sync(input); 56dd4cae8bSChristian Gmeiner 57dd4cae8bSChristian Gmeiner out: 58dd4cae8bSChristian Gmeiner return IRQ_HANDLED; 59dd4cae8bSChristian Gmeiner } 60dd4cae8bSChristian Gmeiner 61dd4cae8bSChristian Gmeiner static int ar1021_i2c_open(struct input_dev *dev) 62dd4cae8bSChristian Gmeiner { 63e55057e8SMartin Kepplinger static const u8 cmd_enable_touch[] = { 64e55057e8SMartin Kepplinger AR1021_CMD, 65e55057e8SMartin Kepplinger 0x01, /* number of bytes after this */ 66e55057e8SMartin Kepplinger AR1021_CMD_ENABLE_TOUCH 67e55057e8SMartin Kepplinger }; 68dd4cae8bSChristian Gmeiner struct ar1021_i2c *ar1021 = input_get_drvdata(dev); 69dd4cae8bSChristian Gmeiner struct i2c_client *client = ar1021->client; 70e55057e8SMartin Kepplinger int error; 71e55057e8SMartin Kepplinger 72e55057e8SMartin Kepplinger error = i2c_master_send(ar1021->client, cmd_enable_touch, 73e55057e8SMartin Kepplinger sizeof(cmd_enable_touch)); 74e55057e8SMartin Kepplinger if (error < 0) 75e55057e8SMartin Kepplinger return error; 76dd4cae8bSChristian Gmeiner 77dd4cae8bSChristian Gmeiner enable_irq(client->irq); 78dd4cae8bSChristian Gmeiner 79dd4cae8bSChristian Gmeiner return 0; 80dd4cae8bSChristian Gmeiner } 81dd4cae8bSChristian Gmeiner 82dd4cae8bSChristian Gmeiner static void ar1021_i2c_close(struct input_dev *dev) 83dd4cae8bSChristian Gmeiner { 84dd4cae8bSChristian Gmeiner struct ar1021_i2c *ar1021 = input_get_drvdata(dev); 85dd4cae8bSChristian Gmeiner struct i2c_client *client = ar1021->client; 86dd4cae8bSChristian Gmeiner 87dd4cae8bSChristian Gmeiner disable_irq(client->irq); 88dd4cae8bSChristian Gmeiner } 89dd4cae8bSChristian Gmeiner 90dd4cae8bSChristian Gmeiner static int ar1021_i2c_probe(struct i2c_client *client, 91dd4cae8bSChristian Gmeiner const struct i2c_device_id *id) 92dd4cae8bSChristian Gmeiner { 93dd4cae8bSChristian Gmeiner struct ar1021_i2c *ar1021; 94dd4cae8bSChristian Gmeiner struct input_dev *input; 95dd4cae8bSChristian Gmeiner int error; 96dd4cae8bSChristian Gmeiner 97dd4cae8bSChristian Gmeiner if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 98dd4cae8bSChristian Gmeiner dev_err(&client->dev, "i2c_check_functionality error\n"); 99dd4cae8bSChristian Gmeiner return -ENXIO; 100dd4cae8bSChristian Gmeiner } 101dd4cae8bSChristian Gmeiner 102dd4cae8bSChristian Gmeiner ar1021 = devm_kzalloc(&client->dev, sizeof(*ar1021), GFP_KERNEL); 103dd4cae8bSChristian Gmeiner if (!ar1021) 104dd4cae8bSChristian Gmeiner return -ENOMEM; 105dd4cae8bSChristian Gmeiner 106dd4cae8bSChristian Gmeiner input = devm_input_allocate_device(&client->dev); 107dd4cae8bSChristian Gmeiner if (!input) 108dd4cae8bSChristian Gmeiner return -ENOMEM; 109dd4cae8bSChristian Gmeiner 110dd4cae8bSChristian Gmeiner ar1021->client = client; 111dd4cae8bSChristian Gmeiner ar1021->input = input; 112dd4cae8bSChristian Gmeiner 113dd4cae8bSChristian Gmeiner input->name = "ar1021 I2C Touchscreen"; 114dd4cae8bSChristian Gmeiner input->id.bustype = BUS_I2C; 115dd4cae8bSChristian Gmeiner input->dev.parent = &client->dev; 116dd4cae8bSChristian Gmeiner input->open = ar1021_i2c_open; 117dd4cae8bSChristian Gmeiner input->close = ar1021_i2c_close; 118dd4cae8bSChristian Gmeiner 11953f0b7f0SMartin Kepplinger __set_bit(INPUT_PROP_DIRECT, input->propbit); 120dd4cae8bSChristian Gmeiner input_set_capability(input, EV_KEY, BTN_TOUCH); 121dd4cae8bSChristian Gmeiner input_set_abs_params(input, ABS_X, 0, AR1021_MAX_X, 0, 0); 122dd4cae8bSChristian Gmeiner input_set_abs_params(input, ABS_Y, 0, AR1021_MAX_Y, 0, 0); 123dd4cae8bSChristian Gmeiner 124dd4cae8bSChristian Gmeiner input_set_drvdata(input, ar1021); 125dd4cae8bSChristian Gmeiner 126dd4cae8bSChristian Gmeiner error = devm_request_threaded_irq(&client->dev, client->irq, 127dd4cae8bSChristian Gmeiner NULL, ar1021_i2c_irq, 12861e977b7SDmitry Torokhov IRQF_ONESHOT, 129dd4cae8bSChristian Gmeiner "ar1021_i2c", ar1021); 130dd4cae8bSChristian Gmeiner if (error) { 131dd4cae8bSChristian Gmeiner dev_err(&client->dev, 132dd4cae8bSChristian Gmeiner "Failed to enable IRQ, error: %d\n", error); 133dd4cae8bSChristian Gmeiner return error; 134dd4cae8bSChristian Gmeiner } 135dd4cae8bSChristian Gmeiner 136dd4cae8bSChristian Gmeiner /* Disable the IRQ, we'll enable it in ar1021_i2c_open() */ 137dd4cae8bSChristian Gmeiner disable_irq(client->irq); 138dd4cae8bSChristian Gmeiner 139dd4cae8bSChristian Gmeiner error = input_register_device(ar1021->input); 140dd4cae8bSChristian Gmeiner if (error) { 141dd4cae8bSChristian Gmeiner dev_err(&client->dev, 142dd4cae8bSChristian Gmeiner "Failed to register input device, error: %d\n", error); 143dd4cae8bSChristian Gmeiner return error; 144dd4cae8bSChristian Gmeiner } 145dd4cae8bSChristian Gmeiner 146dd4cae8bSChristian Gmeiner return 0; 147dd4cae8bSChristian Gmeiner } 148dd4cae8bSChristian Gmeiner 149dd4cae8bSChristian Gmeiner static int __maybe_unused ar1021_i2c_suspend(struct device *dev) 150dd4cae8bSChristian Gmeiner { 151dd4cae8bSChristian Gmeiner struct i2c_client *client = to_i2c_client(dev); 152dd4cae8bSChristian Gmeiner 153dd4cae8bSChristian Gmeiner disable_irq(client->irq); 154dd4cae8bSChristian Gmeiner 155dd4cae8bSChristian Gmeiner return 0; 156dd4cae8bSChristian Gmeiner } 157dd4cae8bSChristian Gmeiner 158dd4cae8bSChristian Gmeiner static int __maybe_unused ar1021_i2c_resume(struct device *dev) 159dd4cae8bSChristian Gmeiner { 160dd4cae8bSChristian Gmeiner struct i2c_client *client = to_i2c_client(dev); 161dd4cae8bSChristian Gmeiner 162dd4cae8bSChristian Gmeiner enable_irq(client->irq); 163dd4cae8bSChristian Gmeiner 164dd4cae8bSChristian Gmeiner return 0; 165dd4cae8bSChristian Gmeiner } 166dd4cae8bSChristian Gmeiner 167dd4cae8bSChristian Gmeiner static SIMPLE_DEV_PM_OPS(ar1021_i2c_pm, ar1021_i2c_suspend, ar1021_i2c_resume); 168dd4cae8bSChristian Gmeiner 169dd4cae8bSChristian Gmeiner static const struct i2c_device_id ar1021_i2c_id[] = { 17095123fc4SDmitry Torokhov { "ar1021", 0 }, 171dd4cae8bSChristian Gmeiner { }, 172dd4cae8bSChristian Gmeiner }; 173dd4cae8bSChristian Gmeiner MODULE_DEVICE_TABLE(i2c, ar1021_i2c_id); 174dd4cae8bSChristian Gmeiner 175245165deSFabian Frederick static const struct of_device_id ar1021_i2c_of_match[] = { 176dd4cae8bSChristian Gmeiner { .compatible = "microchip,ar1021-i2c", }, 177dd4cae8bSChristian Gmeiner { } 178dd4cae8bSChristian Gmeiner }; 179dd4cae8bSChristian Gmeiner MODULE_DEVICE_TABLE(of, ar1021_i2c_of_match); 180dd4cae8bSChristian Gmeiner 181dd4cae8bSChristian Gmeiner static struct i2c_driver ar1021_i2c_driver = { 182dd4cae8bSChristian Gmeiner .driver = { 183dd4cae8bSChristian Gmeiner .name = "ar1021_i2c", 184dd4cae8bSChristian Gmeiner .pm = &ar1021_i2c_pm, 185dd4cae8bSChristian Gmeiner .of_match_table = ar1021_i2c_of_match, 186dd4cae8bSChristian Gmeiner }, 187dd4cae8bSChristian Gmeiner 188dd4cae8bSChristian Gmeiner .probe = ar1021_i2c_probe, 189dd4cae8bSChristian Gmeiner .id_table = ar1021_i2c_id, 190dd4cae8bSChristian Gmeiner }; 191dd4cae8bSChristian Gmeiner module_i2c_driver(ar1021_i2c_driver); 192dd4cae8bSChristian Gmeiner 193dd4cae8bSChristian Gmeiner MODULE_AUTHOR("Christian Gmeiner <christian.gmeiner@gmail.com>"); 194021cbc1eSMartin Kepplinger MODULE_DESCRIPTION("Microchip AR1020 and AR1021 I2C Driver"); 195dd4cae8bSChristian Gmeiner MODULE_LICENSE("GPL"); 196