0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <linux/delay.h>
0015 #include <linux/gpio/consumer.h>
0016 #include <linux/i2c.h>
0017 #include <linux/input.h>
0018 #include <linux/input/mt.h>
0019 #include <linux/input/touchscreen.h>
0020 #include <linux/interrupt.h>
0021 #include <linux/kernel.h>
0022 #include <linux/mod_devicetable.h>
0023 #include <linux/module.h>
0024 #include <linux/regulator/consumer.h>
0025 #include <linux/slab.h>
0026
0027 #define MODE_DATA_RAW 0x5A
0028
0029 #define MAX_SUPPORTED_FINGER_NUM 5
0030
0031 #define CHIP_ON_DELAY_MS 15
0032 #define FIRMWARE_ON_DELAY_MS 50
0033 #define RESET_DELAY_MIN_US 10000
0034 #define RESET_DELAY_MAX_US 11000
0035
0036 struct packet {
0037 u8 xy_hi;
0038 u8 x_low;
0039 u8 y_low;
0040 u8 pressure;
0041 };
0042
0043 struct touch_event {
0044 u8 mode;
0045 struct packet pkt[MAX_SUPPORTED_FINGER_NUM];
0046 u8 proximity;
0047 u8 checksum;
0048 };
0049
0050 struct msg2638_ts_data {
0051 struct i2c_client *client;
0052 struct input_dev *input_dev;
0053 struct touchscreen_properties prop;
0054 struct regulator_bulk_data supplies[2];
0055 struct gpio_desc *reset_gpiod;
0056 };
0057
0058 static u8 msg2638_checksum(u8 *data, u32 length)
0059 {
0060 s32 sum = 0;
0061 u32 i;
0062
0063 for (i = 0; i < length; i++)
0064 sum += data[i];
0065
0066 return (u8)((-sum) & 0xFF);
0067 }
0068
0069 static irqreturn_t msg2638_ts_irq_handler(int irq, void *msg2638_handler)
0070 {
0071 struct msg2638_ts_data *msg2638 = msg2638_handler;
0072 struct i2c_client *client = msg2638->client;
0073 struct input_dev *input = msg2638->input_dev;
0074 struct touch_event touch_event;
0075 u32 len = sizeof(touch_event);
0076 struct i2c_msg msg[] = {
0077 {
0078 .addr = client->addr,
0079 .flags = I2C_M_RD,
0080 .len = sizeof(touch_event),
0081 .buf = (u8 *)&touch_event,
0082 },
0083 };
0084 struct packet *p;
0085 u16 x, y;
0086 int ret;
0087 int i;
0088
0089 ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
0090 if (ret != ARRAY_SIZE(msg)) {
0091 dev_err(&client->dev,
0092 "Failed I2C transfer in irq handler: %d\n",
0093 ret < 0 ? ret : -EIO);
0094 goto out;
0095 }
0096
0097 if (touch_event.mode != MODE_DATA_RAW)
0098 goto out;
0099
0100 if (msg2638_checksum((u8 *)&touch_event, len - 1) !=
0101 touch_event.checksum) {
0102 dev_err(&client->dev, "Failed checksum!\n");
0103 goto out;
0104 }
0105
0106 for (i = 0; i < MAX_SUPPORTED_FINGER_NUM; i++) {
0107 p = &touch_event.pkt[i];
0108
0109
0110 if (p->xy_hi == 0xFF && p->x_low == 0xFF && p->y_low == 0xFF)
0111 continue;
0112
0113 x = (((p->xy_hi & 0xF0) << 4) | p->x_low);
0114 y = (((p->xy_hi & 0x0F) << 8) | p->y_low);
0115
0116 input_mt_slot(input, i);
0117 input_mt_report_slot_state(input, MT_TOOL_FINGER, true);
0118 touchscreen_report_pos(input, &msg2638->prop, x, y, true);
0119 }
0120
0121 input_mt_sync_frame(msg2638->input_dev);
0122 input_sync(msg2638->input_dev);
0123
0124 out:
0125 return IRQ_HANDLED;
0126 }
0127
0128 static void msg2638_reset(struct msg2638_ts_data *msg2638)
0129 {
0130 gpiod_set_value_cansleep(msg2638->reset_gpiod, 1);
0131 usleep_range(RESET_DELAY_MIN_US, RESET_DELAY_MAX_US);
0132 gpiod_set_value_cansleep(msg2638->reset_gpiod, 0);
0133 msleep(FIRMWARE_ON_DELAY_MS);
0134 }
0135
0136 static int msg2638_start(struct msg2638_ts_data *msg2638)
0137 {
0138 int error;
0139
0140 error = regulator_bulk_enable(ARRAY_SIZE(msg2638->supplies),
0141 msg2638->supplies);
0142 if (error) {
0143 dev_err(&msg2638->client->dev,
0144 "Failed to enable regulators: %d\n", error);
0145 return error;
0146 }
0147
0148 msleep(CHIP_ON_DELAY_MS);
0149
0150 msg2638_reset(msg2638);
0151
0152 enable_irq(msg2638->client->irq);
0153
0154 return 0;
0155 }
0156
0157 static int msg2638_stop(struct msg2638_ts_data *msg2638)
0158 {
0159 int error;
0160
0161 disable_irq(msg2638->client->irq);
0162
0163 error = regulator_bulk_disable(ARRAY_SIZE(msg2638->supplies),
0164 msg2638->supplies);
0165 if (error) {
0166 dev_err(&msg2638->client->dev,
0167 "Failed to disable regulators: %d\n", error);
0168 return error;
0169 }
0170
0171 return 0;
0172 }
0173
0174 static int msg2638_input_open(struct input_dev *dev)
0175 {
0176 struct msg2638_ts_data *msg2638 = input_get_drvdata(dev);
0177
0178 return msg2638_start(msg2638);
0179 }
0180
0181 static void msg2638_input_close(struct input_dev *dev)
0182 {
0183 struct msg2638_ts_data *msg2638 = input_get_drvdata(dev);
0184
0185 msg2638_stop(msg2638);
0186 }
0187
0188 static int msg2638_init_input_dev(struct msg2638_ts_data *msg2638)
0189 {
0190 struct device *dev = &msg2638->client->dev;
0191 struct input_dev *input_dev;
0192 int error;
0193
0194 input_dev = devm_input_allocate_device(dev);
0195 if (!input_dev) {
0196 dev_err(dev, "Failed to allocate input device.\n");
0197 return -ENOMEM;
0198 }
0199
0200 input_set_drvdata(input_dev, msg2638);
0201 msg2638->input_dev = input_dev;
0202
0203 input_dev->name = "MStar TouchScreen";
0204 input_dev->phys = "input/ts";
0205 input_dev->id.bustype = BUS_I2C;
0206 input_dev->open = msg2638_input_open;
0207 input_dev->close = msg2638_input_close;
0208
0209 input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_X);
0210 input_set_capability(input_dev, EV_ABS, ABS_MT_POSITION_Y);
0211
0212 touchscreen_parse_properties(input_dev, true, &msg2638->prop);
0213 if (!msg2638->prop.max_x || !msg2638->prop.max_y) {
0214 dev_err(dev, "touchscreen-size-x and/or touchscreen-size-y not set in properties\n");
0215 return -EINVAL;
0216 }
0217
0218 error = input_mt_init_slots(input_dev, MAX_SUPPORTED_FINGER_NUM,
0219 INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
0220 if (error) {
0221 dev_err(dev, "Failed to initialize MT slots: %d\n", error);
0222 return error;
0223 }
0224
0225 error = input_register_device(input_dev);
0226 if (error) {
0227 dev_err(dev, "Failed to register input device: %d\n", error);
0228 return error;
0229 }
0230
0231 return 0;
0232 }
0233
0234 static int msg2638_ts_probe(struct i2c_client *client)
0235 {
0236 struct device *dev = &client->dev;
0237 struct msg2638_ts_data *msg2638;
0238 int error;
0239
0240 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
0241 dev_err(dev, "Failed to assert adapter's support for plain I2C.\n");
0242 return -ENXIO;
0243 }
0244
0245 msg2638 = devm_kzalloc(dev, sizeof(*msg2638), GFP_KERNEL);
0246 if (!msg2638)
0247 return -ENOMEM;
0248
0249 msg2638->client = client;
0250 i2c_set_clientdata(client, msg2638);
0251
0252 msg2638->supplies[0].supply = "vdd";
0253 msg2638->supplies[1].supply = "vddio";
0254 error = devm_regulator_bulk_get(dev, ARRAY_SIZE(msg2638->supplies),
0255 msg2638->supplies);
0256 if (error) {
0257 dev_err(dev, "Failed to get regulators: %d\n", error);
0258 return error;
0259 }
0260
0261 msg2638->reset_gpiod = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
0262 if (IS_ERR(msg2638->reset_gpiod)) {
0263 error = PTR_ERR(msg2638->reset_gpiod);
0264 dev_err(dev, "Failed to request reset GPIO: %d\n", error);
0265 return error;
0266 }
0267
0268 error = msg2638_init_input_dev(msg2638);
0269 if (error) {
0270 dev_err(dev, "Failed to initialize input device: %d\n", error);
0271 return error;
0272 }
0273
0274 error = devm_request_threaded_irq(dev, client->irq,
0275 NULL, msg2638_ts_irq_handler,
0276 IRQF_ONESHOT | IRQF_NO_AUTOEN,
0277 client->name, msg2638);
0278 if (error) {
0279 dev_err(dev, "Failed to request IRQ: %d\n", error);
0280 return error;
0281 }
0282
0283 return 0;
0284 }
0285
0286 static int __maybe_unused msg2638_suspend(struct device *dev)
0287 {
0288 struct i2c_client *client = to_i2c_client(dev);
0289 struct msg2638_ts_data *msg2638 = i2c_get_clientdata(client);
0290
0291 mutex_lock(&msg2638->input_dev->mutex);
0292
0293 if (input_device_enabled(msg2638->input_dev))
0294 msg2638_stop(msg2638);
0295
0296 mutex_unlock(&msg2638->input_dev->mutex);
0297
0298 return 0;
0299 }
0300
0301 static int __maybe_unused msg2638_resume(struct device *dev)
0302 {
0303 struct i2c_client *client = to_i2c_client(dev);
0304 struct msg2638_ts_data *msg2638 = i2c_get_clientdata(client);
0305 int ret = 0;
0306
0307 mutex_lock(&msg2638->input_dev->mutex);
0308
0309 if (input_device_enabled(msg2638->input_dev))
0310 ret = msg2638_start(msg2638);
0311
0312 mutex_unlock(&msg2638->input_dev->mutex);
0313
0314 return ret;
0315 }
0316
0317 static SIMPLE_DEV_PM_OPS(msg2638_pm_ops, msg2638_suspend, msg2638_resume);
0318
0319 static const struct of_device_id msg2638_of_match[] = {
0320 { .compatible = "mstar,msg2638" },
0321 { }
0322 };
0323 MODULE_DEVICE_TABLE(of, msg2638_of_match);
0324
0325 static struct i2c_driver msg2638_ts_driver = {
0326 .probe_new = msg2638_ts_probe,
0327 .driver = {
0328 .name = "MStar-TS",
0329 .pm = &msg2638_pm_ops,
0330 .of_match_table = msg2638_of_match,
0331 },
0332 };
0333 module_i2c_driver(msg2638_ts_driver);
0334
0335 MODULE_AUTHOR("Vincent Knecht <vincent.knecht@mailoo.org>");
0336 MODULE_DESCRIPTION("MStar MSG2638 touchscreen driver");
0337 MODULE_LICENSE("GPL v2");