1*9c92ab61SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 236a281e2SJianchun Bian /* 336a281e2SJianchun Bian * Driver for Pixcir I2C touchscreen controllers. 436a281e2SJianchun Bian * 536a281e2SJianchun Bian * Copyright (C) 2010-2011 Pixcir, Inc. 636a281e2SJianchun Bian */ 736a281e2SJianchun Bian 836a281e2SJianchun Bian #include <linux/delay.h> 936a281e2SJianchun Bian #include <linux/module.h> 1036a281e2SJianchun Bian #include <linux/interrupt.h> 1136a281e2SJianchun Bian #include <linux/slab.h> 1236a281e2SJianchun Bian #include <linux/i2c.h> 1336a281e2SJianchun Bian #include <linux/input.h> 1462e65b7eSRoger Quadros #include <linux/input/mt.h> 15d48259a0SDmitry Torokhov #include <linux/input/touchscreen.h> 160dfc8d41SRoger Quadros #include <linux/gpio.h> 17cb4a5f06SDmitry Torokhov #include <linux/gpio/consumer.h> 18a4054596SRoger Quadros #include <linux/of_device.h> 1928a74c05SDmitry Torokhov #include <linux/platform_data/pixcir_i2c_ts.h> 200bb11e96SHans de Goede #include <asm/unaligned.h> 2136a281e2SJianchun Bian 2236874c7eSRoger Quadros #define PIXCIR_MAX_SLOTS 5 /* Max fingers supported by driver */ 2362e65b7eSRoger Quadros 2436a281e2SJianchun Bian struct pixcir_i2c_ts_data { 2536a281e2SJianchun Bian struct i2c_client *client; 2636a281e2SJianchun Bian struct input_dev *input; 27cb4a5f06SDmitry Torokhov struct gpio_desc *gpio_attb; 2840929167SRoger Quadros struct gpio_desc *gpio_reset; 29bcf5b3deSSander Vermin struct gpio_desc *gpio_enable; 30bcf5b3deSSander Vermin struct gpio_desc *gpio_wake; 31d48259a0SDmitry Torokhov const struct pixcir_i2c_chip_data *chip; 320bb11e96SHans de Goede struct touchscreen_properties prop; 3336874c7eSRoger Quadros int max_fingers; /* Max fingers supported in this instance */ 34d48259a0SDmitry Torokhov bool running; 3536a281e2SJianchun Bian }; 3636a281e2SJianchun Bian 3762e65b7eSRoger Quadros struct pixcir_report_data { 3862e65b7eSRoger Quadros int num_touches; 390bb11e96SHans de Goede struct input_mt_pos pos[PIXCIR_MAX_SLOTS]; 400bb11e96SHans de Goede int ids[PIXCIR_MAX_SLOTS]; 4162e65b7eSRoger Quadros }; 4262e65b7eSRoger Quadros 4362e65b7eSRoger Quadros static void pixcir_ts_parse(struct pixcir_i2c_ts_data *tsdata, 4462e65b7eSRoger Quadros struct pixcir_report_data *report) 4536a281e2SJianchun Bian { 4636874c7eSRoger Quadros u8 rdbuf[2 + PIXCIR_MAX_SLOTS * 5]; 4736874c7eSRoger Quadros u8 wrbuf[1] = { 0 }; 4862e65b7eSRoger Quadros u8 *bufptr; 4936a281e2SJianchun Bian u8 touch; 5062e65b7eSRoger Quadros int ret, i; 5136874c7eSRoger Quadros int readsize; 52d48259a0SDmitry Torokhov const struct pixcir_i2c_chip_data *chip = tsdata->chip; 5362e65b7eSRoger Quadros 5462e65b7eSRoger Quadros memset(report, 0, sizeof(struct pixcir_report_data)); 5536a281e2SJianchun Bian 5636874c7eSRoger Quadros i = chip->has_hw_ids ? 1 : 0; 5736874c7eSRoger Quadros readsize = 2 + tsdata->max_fingers * (4 + i); 5836874c7eSRoger Quadros if (readsize > sizeof(rdbuf)) 5936874c7eSRoger Quadros readsize = sizeof(rdbuf); 6036874c7eSRoger Quadros 6136a281e2SJianchun Bian ret = i2c_master_send(tsdata->client, wrbuf, sizeof(wrbuf)); 6236a281e2SJianchun Bian if (ret != sizeof(wrbuf)) { 6336a281e2SJianchun Bian dev_err(&tsdata->client->dev, 6436a281e2SJianchun Bian "%s: i2c_master_send failed(), ret=%d\n", 6536a281e2SJianchun Bian __func__, ret); 6636a281e2SJianchun Bian return; 6736a281e2SJianchun Bian } 6836a281e2SJianchun Bian 6936874c7eSRoger Quadros ret = i2c_master_recv(tsdata->client, rdbuf, readsize); 70469d7d22SFrodo Lai if (ret != readsize) { 7136a281e2SJianchun Bian dev_err(&tsdata->client->dev, 7236a281e2SJianchun Bian "%s: i2c_master_recv failed(), ret=%d\n", 7336a281e2SJianchun Bian __func__, ret); 7436a281e2SJianchun Bian return; 7536a281e2SJianchun Bian } 7636a281e2SJianchun Bian 7762e65b7eSRoger Quadros touch = rdbuf[0] & 0x7; 7836874c7eSRoger Quadros if (touch > tsdata->max_fingers) 7936874c7eSRoger Quadros touch = tsdata->max_fingers; 8036a281e2SJianchun Bian 8162e65b7eSRoger Quadros report->num_touches = touch; 8262e65b7eSRoger Quadros bufptr = &rdbuf[2]; 8336a281e2SJianchun Bian 8462e65b7eSRoger Quadros for (i = 0; i < touch; i++) { 850bb11e96SHans de Goede touchscreen_set_mt_pos(&report->pos[i], &tsdata->prop, 860bb11e96SHans de Goede get_unaligned_le16(bufptr), 870bb11e96SHans de Goede get_unaligned_le16(bufptr + 2)); 8836874c7eSRoger Quadros if (chip->has_hw_ids) { 890bb11e96SHans de Goede report->ids[i] = bufptr[4]; 9036874c7eSRoger Quadros bufptr = bufptr + 5; 9136874c7eSRoger Quadros } else { 9262e65b7eSRoger Quadros bufptr = bufptr + 4; 9336a281e2SJianchun Bian } 9436a281e2SJianchun Bian } 9536874c7eSRoger Quadros } 9636a281e2SJianchun Bian 9762e65b7eSRoger Quadros static void pixcir_ts_report(struct pixcir_i2c_ts_data *ts, 9862e65b7eSRoger Quadros struct pixcir_report_data *report) 9962e65b7eSRoger Quadros { 10062e65b7eSRoger Quadros int slots[PIXCIR_MAX_SLOTS]; 10162e65b7eSRoger Quadros int n, i, slot; 10262e65b7eSRoger Quadros struct device *dev = &ts->client->dev; 103d48259a0SDmitry Torokhov const struct pixcir_i2c_chip_data *chip = ts->chip; 10462e65b7eSRoger Quadros 10562e65b7eSRoger Quadros n = report->num_touches; 10662e65b7eSRoger Quadros if (n > PIXCIR_MAX_SLOTS) 10762e65b7eSRoger Quadros n = PIXCIR_MAX_SLOTS; 10862e65b7eSRoger Quadros 1090bb11e96SHans de Goede if (!ts->chip->has_hw_ids) 1100bb11e96SHans de Goede input_mt_assign_slots(ts->input, slots, report->pos, n, 0); 11162e65b7eSRoger Quadros 11262e65b7eSRoger Quadros for (i = 0; i < n; i++) { 11336874c7eSRoger Quadros if (chip->has_hw_ids) { 1140bb11e96SHans de Goede slot = input_mt_get_slot_by_key(ts->input, 1150bb11e96SHans de Goede report->ids[i]); 11636874c7eSRoger Quadros if (slot < 0) { 11736874c7eSRoger Quadros dev_dbg(dev, "no free slot for id 0x%x\n", 1180bb11e96SHans de Goede report->ids[i]); 11936874c7eSRoger Quadros continue; 12036874c7eSRoger Quadros } 12136874c7eSRoger Quadros } else { 12262e65b7eSRoger Quadros slot = slots[i]; 12336874c7eSRoger Quadros } 12462e65b7eSRoger Quadros 12562e65b7eSRoger Quadros input_mt_slot(ts->input, slot); 1260bb11e96SHans de Goede input_mt_report_slot_state(ts->input, MT_TOOL_FINGER, true); 12762e65b7eSRoger Quadros 1280bb11e96SHans de Goede input_report_abs(ts->input, ABS_MT_POSITION_X, 1290bb11e96SHans de Goede report->pos[i].x); 1300bb11e96SHans de Goede input_report_abs(ts->input, ABS_MT_POSITION_Y, 1310bb11e96SHans de Goede report->pos[i].y); 13262e65b7eSRoger Quadros 13362e65b7eSRoger Quadros dev_dbg(dev, "%d: slot %d, x %d, y %d\n", 1340bb11e96SHans de Goede i, slot, report->pos[i].x, report->pos[i].y); 13562e65b7eSRoger Quadros } 13662e65b7eSRoger Quadros 13762e65b7eSRoger Quadros input_mt_sync_frame(ts->input); 13862e65b7eSRoger Quadros input_sync(ts->input); 13936a281e2SJianchun Bian } 14036a281e2SJianchun Bian 14136a281e2SJianchun Bian static irqreturn_t pixcir_ts_isr(int irq, void *dev_id) 14236a281e2SJianchun Bian { 14336a281e2SJianchun Bian struct pixcir_i2c_ts_data *tsdata = dev_id; 14462e65b7eSRoger Quadros struct pixcir_report_data report; 14536a281e2SJianchun Bian 1463b36fbb0SRoger Quadros while (tsdata->running) { 14762e65b7eSRoger Quadros /* parse packet */ 14862e65b7eSRoger Quadros pixcir_ts_parse(tsdata, &report); 14936a281e2SJianchun Bian 15062e65b7eSRoger Quadros /* report it */ 15162e65b7eSRoger Quadros pixcir_ts_report(tsdata, &report); 15262e65b7eSRoger Quadros 153127520caSDmitry Torokhov if (gpiod_get_value_cansleep(tsdata->gpio_attb)) { 15462e65b7eSRoger Quadros if (report.num_touches) { 15562e65b7eSRoger Quadros /* 15662e65b7eSRoger Quadros * Last report with no finger up? 15762e65b7eSRoger Quadros * Do it now then. 15862e65b7eSRoger Quadros */ 15962e65b7eSRoger Quadros input_mt_sync_frame(tsdata->input); 16062e65b7eSRoger Quadros input_sync(tsdata->input); 16162e65b7eSRoger Quadros } 16236a281e2SJianchun Bian break; 16362e65b7eSRoger Quadros } 16436a281e2SJianchun Bian 16536a281e2SJianchun Bian msleep(20); 16636a281e2SJianchun Bian } 16736a281e2SJianchun Bian 16836a281e2SJianchun Bian return IRQ_HANDLED; 16936a281e2SJianchun Bian } 17036a281e2SJianchun Bian 17140929167SRoger Quadros static void pixcir_reset(struct pixcir_i2c_ts_data *tsdata) 17240929167SRoger Quadros { 17340929167SRoger Quadros if (!IS_ERR_OR_NULL(tsdata->gpio_reset)) { 17440929167SRoger Quadros gpiod_set_value_cansleep(tsdata->gpio_reset, 1); 17540929167SRoger Quadros ndelay(100); /* datasheet section 1.2.3 says 80ns min. */ 17640929167SRoger Quadros gpiod_set_value_cansleep(tsdata->gpio_reset, 0); 17740929167SRoger Quadros /* wait for controller ready. 100ms guess. */ 17840929167SRoger Quadros msleep(100); 17940929167SRoger Quadros } 18040929167SRoger Quadros } 18140929167SRoger Quadros 1823b36fbb0SRoger Quadros static int pixcir_set_power_mode(struct pixcir_i2c_ts_data *ts, 1833b36fbb0SRoger Quadros enum pixcir_power_mode mode) 1843b36fbb0SRoger Quadros { 1853b36fbb0SRoger Quadros struct device *dev = &ts->client->dev; 1863b36fbb0SRoger Quadros int ret; 1873b36fbb0SRoger Quadros 188bcf5b3deSSander Vermin if (mode == PIXCIR_POWER_ACTIVE || mode == PIXCIR_POWER_IDLE) { 189bcf5b3deSSander Vermin if (ts->gpio_wake) 190bcf5b3deSSander Vermin gpiod_set_value_cansleep(ts->gpio_wake, 1); 191bcf5b3deSSander Vermin } 192bcf5b3deSSander Vermin 1933b36fbb0SRoger Quadros ret = i2c_smbus_read_byte_data(ts->client, PIXCIR_REG_POWER_MODE); 1943b36fbb0SRoger Quadros if (ret < 0) { 1953b36fbb0SRoger Quadros dev_err(dev, "%s: can't read reg 0x%x : %d\n", 1963b36fbb0SRoger Quadros __func__, PIXCIR_REG_POWER_MODE, ret); 1973b36fbb0SRoger Quadros return ret; 1983b36fbb0SRoger Quadros } 1993b36fbb0SRoger Quadros 2003b36fbb0SRoger Quadros ret &= ~PIXCIR_POWER_MODE_MASK; 2013b36fbb0SRoger Quadros ret |= mode; 2023b36fbb0SRoger Quadros 2033b36fbb0SRoger Quadros /* Always AUTO_IDLE */ 2043b36fbb0SRoger Quadros ret |= PIXCIR_POWER_ALLOW_IDLE; 2053b36fbb0SRoger Quadros 2063b36fbb0SRoger Quadros ret = i2c_smbus_write_byte_data(ts->client, PIXCIR_REG_POWER_MODE, ret); 2073b36fbb0SRoger Quadros if (ret < 0) { 2083b36fbb0SRoger Quadros dev_err(dev, "%s: can't write reg 0x%x : %d\n", 2093b36fbb0SRoger Quadros __func__, PIXCIR_REG_POWER_MODE, ret); 2103b36fbb0SRoger Quadros return ret; 2113b36fbb0SRoger Quadros } 2123b36fbb0SRoger Quadros 213bcf5b3deSSander Vermin if (mode == PIXCIR_POWER_HALT) { 214bcf5b3deSSander Vermin if (ts->gpio_wake) 215bcf5b3deSSander Vermin gpiod_set_value_cansleep(ts->gpio_wake, 0); 216bcf5b3deSSander Vermin } 217bcf5b3deSSander Vermin 2183b36fbb0SRoger Quadros return 0; 2193b36fbb0SRoger Quadros } 2203b36fbb0SRoger Quadros 2213b36fbb0SRoger Quadros /* 2223b36fbb0SRoger Quadros * Set the interrupt mode for the device i.e. ATTB line behaviour 2233b36fbb0SRoger Quadros * 2243b36fbb0SRoger Quadros * @polarity : 1 for active high, 0 for active low. 2253b36fbb0SRoger Quadros */ 2263b36fbb0SRoger Quadros static int pixcir_set_int_mode(struct pixcir_i2c_ts_data *ts, 2273b36fbb0SRoger Quadros enum pixcir_int_mode mode, bool polarity) 2283b36fbb0SRoger Quadros { 2293b36fbb0SRoger Quadros struct device *dev = &ts->client->dev; 2303b36fbb0SRoger Quadros int ret; 2313b36fbb0SRoger Quadros 2323b36fbb0SRoger Quadros ret = i2c_smbus_read_byte_data(ts->client, PIXCIR_REG_INT_MODE); 2333b36fbb0SRoger Quadros if (ret < 0) { 2343b36fbb0SRoger Quadros dev_err(dev, "%s: can't read reg 0x%x : %d\n", 2353b36fbb0SRoger Quadros __func__, PIXCIR_REG_INT_MODE, ret); 2363b36fbb0SRoger Quadros return ret; 2373b36fbb0SRoger Quadros } 2383b36fbb0SRoger Quadros 2393b36fbb0SRoger Quadros ret &= ~PIXCIR_INT_MODE_MASK; 2403b36fbb0SRoger Quadros ret |= mode; 2413b36fbb0SRoger Quadros 2423b36fbb0SRoger Quadros if (polarity) 2433b36fbb0SRoger Quadros ret |= PIXCIR_INT_POL_HIGH; 2443b36fbb0SRoger Quadros else 2453b36fbb0SRoger Quadros ret &= ~PIXCIR_INT_POL_HIGH; 2463b36fbb0SRoger Quadros 2473b36fbb0SRoger Quadros ret = i2c_smbus_write_byte_data(ts->client, PIXCIR_REG_INT_MODE, ret); 2483b36fbb0SRoger Quadros if (ret < 0) { 2493b36fbb0SRoger Quadros dev_err(dev, "%s: can't write reg 0x%x : %d\n", 2503b36fbb0SRoger Quadros __func__, PIXCIR_REG_INT_MODE, ret); 2513b36fbb0SRoger Quadros return ret; 2523b36fbb0SRoger Quadros } 2533b36fbb0SRoger Quadros 2543b36fbb0SRoger Quadros return 0; 2553b36fbb0SRoger Quadros } 2563b36fbb0SRoger Quadros 2573b36fbb0SRoger Quadros /* 2583b36fbb0SRoger Quadros * Enable/disable interrupt generation 2593b36fbb0SRoger Quadros */ 2603b36fbb0SRoger Quadros static int pixcir_int_enable(struct pixcir_i2c_ts_data *ts, bool enable) 2613b36fbb0SRoger Quadros { 2623b36fbb0SRoger Quadros struct device *dev = &ts->client->dev; 2633b36fbb0SRoger Quadros int ret; 2643b36fbb0SRoger Quadros 2653b36fbb0SRoger Quadros ret = i2c_smbus_read_byte_data(ts->client, PIXCIR_REG_INT_MODE); 2663b36fbb0SRoger Quadros if (ret < 0) { 2673b36fbb0SRoger Quadros dev_err(dev, "%s: can't read reg 0x%x : %d\n", 2683b36fbb0SRoger Quadros __func__, PIXCIR_REG_INT_MODE, ret); 2693b36fbb0SRoger Quadros return ret; 2703b36fbb0SRoger Quadros } 2713b36fbb0SRoger Quadros 2723b36fbb0SRoger Quadros if (enable) 2733b36fbb0SRoger Quadros ret |= PIXCIR_INT_ENABLE; 2743b36fbb0SRoger Quadros else 2753b36fbb0SRoger Quadros ret &= ~PIXCIR_INT_ENABLE; 2763b36fbb0SRoger Quadros 2773b36fbb0SRoger Quadros ret = i2c_smbus_write_byte_data(ts->client, PIXCIR_REG_INT_MODE, ret); 2783b36fbb0SRoger Quadros if (ret < 0) { 2793b36fbb0SRoger Quadros dev_err(dev, "%s: can't write reg 0x%x : %d\n", 2803b36fbb0SRoger Quadros __func__, PIXCIR_REG_INT_MODE, ret); 2813b36fbb0SRoger Quadros return ret; 2823b36fbb0SRoger Quadros } 2833b36fbb0SRoger Quadros 2843b36fbb0SRoger Quadros return 0; 2853b36fbb0SRoger Quadros } 2863b36fbb0SRoger Quadros 2873b36fbb0SRoger Quadros static int pixcir_start(struct pixcir_i2c_ts_data *ts) 2883b36fbb0SRoger Quadros { 2893b36fbb0SRoger Quadros struct device *dev = &ts->client->dev; 2903b36fbb0SRoger Quadros int error; 2913b36fbb0SRoger Quadros 292bcf5b3deSSander Vermin if (ts->gpio_enable) { 293bcf5b3deSSander Vermin gpiod_set_value_cansleep(ts->gpio_enable, 1); 294bcf5b3deSSander Vermin msleep(100); 295bcf5b3deSSander Vermin } 296bcf5b3deSSander Vermin 2973b36fbb0SRoger Quadros /* LEVEL_TOUCH interrupt with active low polarity */ 2983b36fbb0SRoger Quadros error = pixcir_set_int_mode(ts, PIXCIR_INT_LEVEL_TOUCH, 0); 2993b36fbb0SRoger Quadros if (error) { 3003b36fbb0SRoger Quadros dev_err(dev, "Failed to set interrupt mode: %d\n", error); 3013b36fbb0SRoger Quadros return error; 3023b36fbb0SRoger Quadros } 3033b36fbb0SRoger Quadros 3043b36fbb0SRoger Quadros ts->running = true; 3053b36fbb0SRoger Quadros mb(); /* Update status before IRQ can fire */ 3063b36fbb0SRoger Quadros 3073b36fbb0SRoger Quadros /* enable interrupt generation */ 3083b36fbb0SRoger Quadros error = pixcir_int_enable(ts, true); 3093b36fbb0SRoger Quadros if (error) { 3103b36fbb0SRoger Quadros dev_err(dev, "Failed to enable interrupt generation: %d\n", 3113b36fbb0SRoger Quadros error); 3123b36fbb0SRoger Quadros return error; 3133b36fbb0SRoger Quadros } 3143b36fbb0SRoger Quadros 3153b36fbb0SRoger Quadros return 0; 3163b36fbb0SRoger Quadros } 3173b36fbb0SRoger Quadros 3183b36fbb0SRoger Quadros static int pixcir_stop(struct pixcir_i2c_ts_data *ts) 3193b36fbb0SRoger Quadros { 3203b36fbb0SRoger Quadros int error; 3213b36fbb0SRoger Quadros 3223b36fbb0SRoger Quadros /* Disable interrupt generation */ 3233b36fbb0SRoger Quadros error = pixcir_int_enable(ts, false); 3243b36fbb0SRoger Quadros if (error) { 3253b36fbb0SRoger Quadros dev_err(&ts->client->dev, 3263b36fbb0SRoger Quadros "Failed to disable interrupt generation: %d\n", 3273b36fbb0SRoger Quadros error); 3283b36fbb0SRoger Quadros return error; 3293b36fbb0SRoger Quadros } 3303b36fbb0SRoger Quadros 3313b36fbb0SRoger Quadros /* Exit ISR if running, no more report parsing */ 3323b36fbb0SRoger Quadros ts->running = false; 3333b36fbb0SRoger Quadros mb(); /* update status before we synchronize irq */ 3343b36fbb0SRoger Quadros 3353b36fbb0SRoger Quadros /* Wait till running ISR is complete */ 3363b36fbb0SRoger Quadros synchronize_irq(ts->client->irq); 3373b36fbb0SRoger Quadros 338bcf5b3deSSander Vermin if (ts->gpio_enable) 339bcf5b3deSSander Vermin gpiod_set_value_cansleep(ts->gpio_enable, 0); 340bcf5b3deSSander Vermin 3413b36fbb0SRoger Quadros return 0; 3423b36fbb0SRoger Quadros } 3433b36fbb0SRoger Quadros 3443b36fbb0SRoger Quadros static int pixcir_input_open(struct input_dev *dev) 3453b36fbb0SRoger Quadros { 3463b36fbb0SRoger Quadros struct pixcir_i2c_ts_data *ts = input_get_drvdata(dev); 3473b36fbb0SRoger Quadros 3483b36fbb0SRoger Quadros return pixcir_start(ts); 3493b36fbb0SRoger Quadros } 3503b36fbb0SRoger Quadros 3513b36fbb0SRoger Quadros static void pixcir_input_close(struct input_dev *dev) 3523b36fbb0SRoger Quadros { 3533b36fbb0SRoger Quadros struct pixcir_i2c_ts_data *ts = input_get_drvdata(dev); 3543b36fbb0SRoger Quadros 3553b36fbb0SRoger Quadros pixcir_stop(ts); 3563b36fbb0SRoger Quadros } 3573b36fbb0SRoger Quadros 35802b6a58bSJingoo Han static int __maybe_unused pixcir_i2c_ts_suspend(struct device *dev) 35936a281e2SJianchun Bian { 36036a281e2SJianchun Bian struct i2c_client *client = to_i2c_client(dev); 3617cdcb8d1SRoger Quadros struct pixcir_i2c_ts_data *ts = i2c_get_clientdata(client); 3627cdcb8d1SRoger Quadros struct input_dev *input = ts->input; 3637cdcb8d1SRoger Quadros int ret = 0; 36436a281e2SJianchun Bian 3657cdcb8d1SRoger Quadros mutex_lock(&input->mutex); 3667cdcb8d1SRoger Quadros 3677cdcb8d1SRoger Quadros if (device_may_wakeup(&client->dev)) { 3687cdcb8d1SRoger Quadros if (!input->users) { 3697cdcb8d1SRoger Quadros ret = pixcir_start(ts); 3707cdcb8d1SRoger Quadros if (ret) { 3717cdcb8d1SRoger Quadros dev_err(dev, "Failed to start\n"); 3727cdcb8d1SRoger Quadros goto unlock; 3737cdcb8d1SRoger Quadros } 3747cdcb8d1SRoger Quadros } 3757cdcb8d1SRoger Quadros } else if (input->users) { 3767cdcb8d1SRoger Quadros ret = pixcir_stop(ts); 3777cdcb8d1SRoger Quadros } 37836a281e2SJianchun Bian 3797cdcb8d1SRoger Quadros unlock: 3807cdcb8d1SRoger Quadros mutex_unlock(&input->mutex); 3817cdcb8d1SRoger Quadros 3827cdcb8d1SRoger Quadros return ret; 38336a281e2SJianchun Bian } 38436a281e2SJianchun Bian 38502b6a58bSJingoo Han static int __maybe_unused pixcir_i2c_ts_resume(struct device *dev) 38636a281e2SJianchun Bian { 38736a281e2SJianchun Bian struct i2c_client *client = to_i2c_client(dev); 3887cdcb8d1SRoger Quadros struct pixcir_i2c_ts_data *ts = i2c_get_clientdata(client); 3897cdcb8d1SRoger Quadros struct input_dev *input = ts->input; 3907cdcb8d1SRoger Quadros int ret = 0; 39136a281e2SJianchun Bian 3927cdcb8d1SRoger Quadros mutex_lock(&input->mutex); 3937cdcb8d1SRoger Quadros 3947cdcb8d1SRoger Quadros if (device_may_wakeup(&client->dev)) { 3957cdcb8d1SRoger Quadros if (!input->users) { 3967cdcb8d1SRoger Quadros ret = pixcir_stop(ts); 3977cdcb8d1SRoger Quadros if (ret) { 3987cdcb8d1SRoger Quadros dev_err(dev, "Failed to stop\n"); 3997cdcb8d1SRoger Quadros goto unlock; 4007cdcb8d1SRoger Quadros } 4017cdcb8d1SRoger Quadros } 4027cdcb8d1SRoger Quadros } else if (input->users) { 4037cdcb8d1SRoger Quadros ret = pixcir_start(ts); 4047cdcb8d1SRoger Quadros } 4057cdcb8d1SRoger Quadros 4067cdcb8d1SRoger Quadros unlock: 4077cdcb8d1SRoger Quadros mutex_unlock(&input->mutex); 4087cdcb8d1SRoger Quadros 4097cdcb8d1SRoger Quadros return ret; 41036a281e2SJianchun Bian } 41136a281e2SJianchun Bian 41236a281e2SJianchun Bian static SIMPLE_DEV_PM_OPS(pixcir_dev_pm_ops, 41336a281e2SJianchun Bian pixcir_i2c_ts_suspend, pixcir_i2c_ts_resume); 41436a281e2SJianchun Bian 415a4054596SRoger Quadros #ifdef CONFIG_OF 416a4054596SRoger Quadros static const struct of_device_id pixcir_of_match[]; 417a4054596SRoger Quadros 418d48259a0SDmitry Torokhov static int pixcir_parse_dt(struct device *dev, 419d48259a0SDmitry Torokhov struct pixcir_i2c_ts_data *tsdata) 420a4054596SRoger Quadros { 4218ffef3ccSLABBE Corentin tsdata->chip = of_device_get_match_data(dev); 422d48259a0SDmitry Torokhov if (!tsdata->chip) 423d48259a0SDmitry Torokhov return -EINVAL; 424a4054596SRoger Quadros 425d48259a0SDmitry Torokhov return 0; 426a4054596SRoger Quadros } 427a4054596SRoger Quadros #else 428d48259a0SDmitry Torokhov static int pixcir_parse_dt(struct device *dev, 429d48259a0SDmitry Torokhov struct pixcir_i2c_ts_data *tsdata) 430a4054596SRoger Quadros { 431d48259a0SDmitry Torokhov return -EINVAL; 432a4054596SRoger Quadros } 433a4054596SRoger Quadros #endif 434a4054596SRoger Quadros 4355298cc4cSBill Pemberton static int pixcir_i2c_ts_probe(struct i2c_client *client, 43636a281e2SJianchun Bian const struct i2c_device_id *id) 43736a281e2SJianchun Bian { 438c838cb3dSJingoo Han const struct pixcir_ts_platform_data *pdata = 439c838cb3dSJingoo Han dev_get_platdata(&client->dev); 440e9d4718dSRoger Quadros struct device *dev = &client->dev; 44136a281e2SJianchun Bian struct pixcir_i2c_ts_data *tsdata; 44236a281e2SJianchun Bian struct input_dev *input; 44336a281e2SJianchun Bian int error; 44436a281e2SJianchun Bian 445d48259a0SDmitry Torokhov tsdata = devm_kzalloc(dev, sizeof(*tsdata), GFP_KERNEL); 446d48259a0SDmitry Torokhov if (!tsdata) 447d48259a0SDmitry Torokhov return -ENOMEM; 448a4054596SRoger Quadros 449d48259a0SDmitry Torokhov if (pdata) { 450d48259a0SDmitry Torokhov tsdata->chip = &pdata->chip; 451d48259a0SDmitry Torokhov } else if (dev->of_node) { 452d48259a0SDmitry Torokhov error = pixcir_parse_dt(dev, tsdata); 453d48259a0SDmitry Torokhov if (error) 454d48259a0SDmitry Torokhov return error; 455d48259a0SDmitry Torokhov } else { 456d7ddf154SGuenter Roeck dev_err(dev, "platform data not defined\n"); 45736a281e2SJianchun Bian return -EINVAL; 45836a281e2SJianchun Bian } 45936a281e2SJianchun Bian 460d48259a0SDmitry Torokhov if (!tsdata->chip->max_fingers) { 461d48259a0SDmitry Torokhov dev_err(dev, "Invalid max_fingers in chip data\n"); 46236874c7eSRoger Quadros return -EINVAL; 46336874c7eSRoger Quadros } 46436874c7eSRoger Quadros 465e9d4718dSRoger Quadros input = devm_input_allocate_device(dev); 466e9d4718dSRoger Quadros if (!input) { 467e9d4718dSRoger Quadros dev_err(dev, "Failed to allocate input device\n"); 468e9d4718dSRoger Quadros return -ENOMEM; 46936a281e2SJianchun Bian } 47036a281e2SJianchun Bian 47136a281e2SJianchun Bian tsdata->client = client; 47236a281e2SJianchun Bian tsdata->input = input; 47336a281e2SJianchun Bian 47436a281e2SJianchun Bian input->name = client->name; 47536a281e2SJianchun Bian input->id.bustype = BUS_I2C; 4763b36fbb0SRoger Quadros input->open = pixcir_input_open; 4773b36fbb0SRoger Quadros input->close = pixcir_input_close; 478d7ddf154SGuenter Roeck input->dev.parent = dev; 47936a281e2SJianchun Bian 480d48259a0SDmitry Torokhov if (pdata) { 48136a281e2SJianchun Bian input_set_abs_params(input, ABS_MT_POSITION_X, 0, pdata->x_max, 0, 0); 48236a281e2SJianchun Bian input_set_abs_params(input, ABS_MT_POSITION_Y, 0, pdata->y_max, 0, 0); 483d48259a0SDmitry Torokhov } else { 484d48259a0SDmitry Torokhov input_set_capability(input, EV_ABS, ABS_MT_POSITION_X); 485d48259a0SDmitry Torokhov input_set_capability(input, EV_ABS, ABS_MT_POSITION_Y); 4860bb11e96SHans de Goede touchscreen_parse_properties(input, true, &tsdata->prop); 487d48259a0SDmitry Torokhov if (!input_abs_get_max(input, ABS_MT_POSITION_X) || 488d48259a0SDmitry Torokhov !input_abs_get_max(input, ABS_MT_POSITION_Y)) { 489d48259a0SDmitry Torokhov dev_err(dev, "Touchscreen size is not specified\n"); 490d48259a0SDmitry Torokhov return -EINVAL; 491d48259a0SDmitry Torokhov } 492d48259a0SDmitry Torokhov } 49336a281e2SJianchun Bian 494d48259a0SDmitry Torokhov tsdata->max_fingers = tsdata->chip->max_fingers; 49536874c7eSRoger Quadros if (tsdata->max_fingers > PIXCIR_MAX_SLOTS) { 49636874c7eSRoger Quadros tsdata->max_fingers = PIXCIR_MAX_SLOTS; 49736874c7eSRoger Quadros dev_info(dev, "Limiting maximum fingers to %d\n", 49836874c7eSRoger Quadros tsdata->max_fingers); 49936874c7eSRoger Quadros } 50036874c7eSRoger Quadros 50136874c7eSRoger Quadros error = input_mt_init_slots(input, tsdata->max_fingers, 50262e65b7eSRoger Quadros INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED); 50362e65b7eSRoger Quadros if (error) { 50462e65b7eSRoger Quadros dev_err(dev, "Error initializing Multi-Touch slots\n"); 50562e65b7eSRoger Quadros return error; 50662e65b7eSRoger Quadros } 50762e65b7eSRoger Quadros 50836a281e2SJianchun Bian input_set_drvdata(input, tsdata); 50936a281e2SJianchun Bian 510cb4a5f06SDmitry Torokhov tsdata->gpio_attb = devm_gpiod_get(dev, "attb", GPIOD_IN); 511cb4a5f06SDmitry Torokhov if (IS_ERR(tsdata->gpio_attb)) { 512cb4a5f06SDmitry Torokhov error = PTR_ERR(tsdata->gpio_attb); 513cb4a5f06SDmitry Torokhov dev_err(dev, "Failed to request ATTB gpio: %d\n", error); 5140dfc8d41SRoger Quadros return error; 5150dfc8d41SRoger Quadros } 5160dfc8d41SRoger Quadros 51740929167SRoger Quadros tsdata->gpio_reset = devm_gpiod_get_optional(dev, "reset", 51840929167SRoger Quadros GPIOD_OUT_LOW); 51940929167SRoger Quadros if (IS_ERR(tsdata->gpio_reset)) { 52040929167SRoger Quadros error = PTR_ERR(tsdata->gpio_reset); 52140929167SRoger Quadros dev_err(dev, "Failed to request RESET gpio: %d\n", error); 52240929167SRoger Quadros return error; 52340929167SRoger Quadros } 52440929167SRoger Quadros 525bcf5b3deSSander Vermin tsdata->gpio_wake = devm_gpiod_get_optional(dev, "wake", 526bcf5b3deSSander Vermin GPIOD_OUT_HIGH); 527bcf5b3deSSander Vermin if (IS_ERR(tsdata->gpio_wake)) { 528bcf5b3deSSander Vermin error = PTR_ERR(tsdata->gpio_wake); 529bcf5b3deSSander Vermin if (error != -EPROBE_DEFER) 530bcf5b3deSSander Vermin dev_err(dev, "Failed to get wake gpio: %d\n", error); 531bcf5b3deSSander Vermin return error; 532bcf5b3deSSander Vermin } 533bcf5b3deSSander Vermin 534bcf5b3deSSander Vermin tsdata->gpio_enable = devm_gpiod_get_optional(dev, "enable", 535bcf5b3deSSander Vermin GPIOD_OUT_HIGH); 536bcf5b3deSSander Vermin if (IS_ERR(tsdata->gpio_enable)) { 537bcf5b3deSSander Vermin error = PTR_ERR(tsdata->gpio_enable); 538bcf5b3deSSander Vermin if (error != -EPROBE_DEFER) 539bcf5b3deSSander Vermin dev_err(dev, "Failed to get enable gpio: %d\n", error); 540bcf5b3deSSander Vermin return error; 541bcf5b3deSSander Vermin } 542bcf5b3deSSander Vermin 543bcf5b3deSSander Vermin if (tsdata->gpio_enable) 544bcf5b3deSSander Vermin msleep(100); 545bcf5b3deSSander Vermin 546e9d4718dSRoger Quadros error = devm_request_threaded_irq(dev, client->irq, NULL, pixcir_ts_isr, 5479b7e31bbSLars-Peter Clausen IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 54836a281e2SJianchun Bian client->name, tsdata); 54936a281e2SJianchun Bian if (error) { 550e9d4718dSRoger Quadros dev_err(dev, "failed to request irq %d\n", client->irq); 551e9d4718dSRoger Quadros return error; 55236a281e2SJianchun Bian } 55336a281e2SJianchun Bian 55440929167SRoger Quadros pixcir_reset(tsdata); 55540929167SRoger Quadros 5563b36fbb0SRoger Quadros /* Always be in IDLE mode to save power, device supports auto wake */ 5573b36fbb0SRoger Quadros error = pixcir_set_power_mode(tsdata, PIXCIR_POWER_IDLE); 5583b36fbb0SRoger Quadros if (error) { 5593b36fbb0SRoger Quadros dev_err(dev, "Failed to set IDLE mode\n"); 5603b36fbb0SRoger Quadros return error; 5613b36fbb0SRoger Quadros } 5623b36fbb0SRoger Quadros 5633b36fbb0SRoger Quadros /* Stop device till opened */ 5643b36fbb0SRoger Quadros error = pixcir_stop(tsdata); 5653b36fbb0SRoger Quadros if (error) 5663b36fbb0SRoger Quadros return error; 5673b36fbb0SRoger Quadros 56836a281e2SJianchun Bian error = input_register_device(input); 56936a281e2SJianchun Bian if (error) 570e9d4718dSRoger Quadros return error; 57136a281e2SJianchun Bian 5727cdcb8d1SRoger Quadros i2c_set_clientdata(client, tsdata); 57336a281e2SJianchun Bian 57436a281e2SJianchun Bian return 0; 57536a281e2SJianchun Bian } 57636a281e2SJianchun Bian 57736a281e2SJianchun Bian static const struct i2c_device_id pixcir_i2c_ts_id[] = { 57836a281e2SJianchun Bian { "pixcir_ts", 0 }, 579a4054596SRoger Quadros { "pixcir_tangoc", 0 }, 58036a281e2SJianchun Bian { } 58136a281e2SJianchun Bian }; 58236a281e2SJianchun Bian MODULE_DEVICE_TABLE(i2c, pixcir_i2c_ts_id); 58336a281e2SJianchun Bian 584a4054596SRoger Quadros #ifdef CONFIG_OF 585a4054596SRoger Quadros static const struct pixcir_i2c_chip_data pixcir_ts_data = { 586a4054596SRoger Quadros .max_fingers = 2, 587a4054596SRoger Quadros /* no hw id support */ 588a4054596SRoger Quadros }; 589a4054596SRoger Quadros 590a4054596SRoger Quadros static const struct pixcir_i2c_chip_data pixcir_tangoc_data = { 591a4054596SRoger Quadros .max_fingers = 5, 592a4054596SRoger Quadros .has_hw_ids = true, 593a4054596SRoger Quadros }; 594a4054596SRoger Quadros 595a4054596SRoger Quadros static const struct of_device_id pixcir_of_match[] = { 596a4054596SRoger Quadros { .compatible = "pixcir,pixcir_ts", .data = &pixcir_ts_data }, 597a4054596SRoger Quadros { .compatible = "pixcir,pixcir_tangoc", .data = &pixcir_tangoc_data }, 598a4054596SRoger Quadros { } 599a4054596SRoger Quadros }; 600a4054596SRoger Quadros MODULE_DEVICE_TABLE(of, pixcir_of_match); 601a4054596SRoger Quadros #endif 602a4054596SRoger Quadros 60336a281e2SJianchun Bian static struct i2c_driver pixcir_i2c_ts_driver = { 60436a281e2SJianchun Bian .driver = { 60536a281e2SJianchun Bian .name = "pixcir_ts", 60636a281e2SJianchun Bian .pm = &pixcir_dev_pm_ops, 607a4054596SRoger Quadros .of_match_table = of_match_ptr(pixcir_of_match), 60836a281e2SJianchun Bian }, 60936a281e2SJianchun Bian .probe = pixcir_i2c_ts_probe, 61036a281e2SJianchun Bian .id_table = pixcir_i2c_ts_id, 61136a281e2SJianchun Bian }; 61236a281e2SJianchun Bian 6134a533835SDmitry Torokhov module_i2c_driver(pixcir_i2c_ts_driver); 61436a281e2SJianchun Bian 61536a281e2SJianchun Bian MODULE_AUTHOR("Jianchun Bian <jcbian@pixcir.com.cn>, Dequan Meng <dqmeng@pixcir.com.cn>"); 61636a281e2SJianchun Bian MODULE_DESCRIPTION("Pixcir I2C Touchscreen Driver"); 61736a281e2SJianchun Bian MODULE_LICENSE("GPL"); 618