diff options
author | Nick Dyer <nick.dyer@itdev.co.uk> | 2014-07-23 15:21:26 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2014-07-23 16:25:10 -0400 |
commit | 7a53d60926714541e2250b7c55100883cdcaf787 (patch) | |
tree | 8c8b436283c38ec8d7dcccfb2020ff369c83bdbc | |
parent | dd24dcf566d0787297953bcaa3a7739586535a33 (diff) |
Input: atmel_mxt_ts - move input device init into separate function
It is useful to initialise the input device later:
- Screen parameters may not be not known yet, for instance if waiting for
firmware loader to return.
- Device may be in bootloader mode on probe (but could still be recovered by
firmware download).
In addition, later devices have a different touchscreen object (T100) which
requires handling differently.
This also reduces the complexity of the probe function.
Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk>
Acked-by: Yufeng Shen <miletus@chromium.org>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
-rw-r--r-- | drivers/input/touchscreen/atmel_mxt_ts.c | 191 |
1 files changed, 107 insertions, 84 deletions
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 02c374d52967..a248414642d9 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c | |||
@@ -1047,6 +1047,9 @@ static int mxt_get_object_table(struct mxt_data *data) | |||
1047 | 1047 | ||
1048 | static void mxt_free_object_table(struct mxt_data *data) | 1048 | static void mxt_free_object_table(struct mxt_data *data) |
1049 | { | 1049 | { |
1050 | input_unregister_device(data->input_dev); | ||
1051 | data->input_dev = NULL; | ||
1052 | |||
1050 | kfree(data->object_table); | 1053 | kfree(data->object_table); |
1051 | data->object_table = NULL; | 1054 | data->object_table = NULL; |
1052 | data->T6_reportid = 0; | 1055 | data->T6_reportid = 0; |
@@ -1103,6 +1106,102 @@ static int mxt_read_t9_resolution(struct mxt_data *data) | |||
1103 | return 0; | 1106 | return 0; |
1104 | } | 1107 | } |
1105 | 1108 | ||
1109 | static int mxt_input_open(struct input_dev *dev); | ||
1110 | static void mxt_input_close(struct input_dev *dev); | ||
1111 | |||
1112 | static int mxt_initialize_t9_input_device(struct mxt_data *data) | ||
1113 | { | ||
1114 | struct device *dev = &data->client->dev; | ||
1115 | const struct mxt_platform_data *pdata = data->pdata; | ||
1116 | struct input_dev *input_dev; | ||
1117 | int error; | ||
1118 | unsigned int num_mt_slots; | ||
1119 | unsigned int mt_flags = 0; | ||
1120 | int i; | ||
1121 | |||
1122 | error = mxt_read_t9_resolution(data); | ||
1123 | if (error) | ||
1124 | dev_warn(dev, "Failed to initialize T9 resolution\n"); | ||
1125 | |||
1126 | input_dev = input_allocate_device(); | ||
1127 | if (!input_dev) { | ||
1128 | dev_err(dev, "Failed to allocate memory\n"); | ||
1129 | return -ENOMEM; | ||
1130 | } | ||
1131 | |||
1132 | input_dev->name = "Atmel maXTouch Touchscreen"; | ||
1133 | input_dev->phys = data->phys; | ||
1134 | input_dev->id.bustype = BUS_I2C; | ||
1135 | input_dev->dev.parent = dev; | ||
1136 | input_dev->open = mxt_input_open; | ||
1137 | input_dev->close = mxt_input_close; | ||
1138 | |||
1139 | __set_bit(EV_ABS, input_dev->evbit); | ||
1140 | __set_bit(EV_KEY, input_dev->evbit); | ||
1141 | __set_bit(BTN_TOUCH, input_dev->keybit); | ||
1142 | |||
1143 | if (pdata->t19_num_keys) { | ||
1144 | __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit); | ||
1145 | |||
1146 | for (i = 0; i < pdata->t19_num_keys; i++) | ||
1147 | if (pdata->t19_keymap[i] != KEY_RESERVED) | ||
1148 | input_set_capability(input_dev, EV_KEY, | ||
1149 | pdata->t19_keymap[i]); | ||
1150 | |||
1151 | mt_flags |= INPUT_MT_POINTER; | ||
1152 | |||
1153 | input_abs_set_res(input_dev, ABS_X, MXT_PIXELS_PER_MM); | ||
1154 | input_abs_set_res(input_dev, ABS_Y, MXT_PIXELS_PER_MM); | ||
1155 | input_abs_set_res(input_dev, ABS_MT_POSITION_X, | ||
1156 | MXT_PIXELS_PER_MM); | ||
1157 | input_abs_set_res(input_dev, ABS_MT_POSITION_Y, | ||
1158 | MXT_PIXELS_PER_MM); | ||
1159 | |||
1160 | input_dev->name = "Atmel maXTouch Touchpad"; | ||
1161 | } | ||
1162 | |||
1163 | /* For single touch */ | ||
1164 | input_set_abs_params(input_dev, ABS_X, | ||
1165 | 0, data->max_x, 0, 0); | ||
1166 | input_set_abs_params(input_dev, ABS_Y, | ||
1167 | 0, data->max_y, 0, 0); | ||
1168 | input_set_abs_params(input_dev, ABS_PRESSURE, | ||
1169 | 0, 255, 0, 0); | ||
1170 | |||
1171 | /* For multi touch */ | ||
1172 | num_mt_slots = data->T9_reportid_max - data->T9_reportid_min + 1; | ||
1173 | error = input_mt_init_slots(input_dev, num_mt_slots, mt_flags); | ||
1174 | if (error) { | ||
1175 | dev_err(dev, "Error %d initialising slots\n", error); | ||
1176 | goto err_free_mem; | ||
1177 | } | ||
1178 | |||
1179 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, | ||
1180 | 0, MXT_MAX_AREA, 0, 0); | ||
1181 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | ||
1182 | 0, data->max_x, 0, 0); | ||
1183 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, | ||
1184 | 0, data->max_y, 0, 0); | ||
1185 | input_set_abs_params(input_dev, ABS_MT_PRESSURE, | ||
1186 | 0, 255, 0, 0); | ||
1187 | |||
1188 | input_set_drvdata(input_dev, data); | ||
1189 | |||
1190 | error = input_register_device(input_dev); | ||
1191 | if (error) { | ||
1192 | dev_err(dev, "Error %d registering input device\n", error); | ||
1193 | goto err_free_mem; | ||
1194 | } | ||
1195 | |||
1196 | data->input_dev = input_dev; | ||
1197 | |||
1198 | return 0; | ||
1199 | |||
1200 | err_free_mem: | ||
1201 | input_free_device(input_dev); | ||
1202 | return error; | ||
1203 | } | ||
1204 | |||
1106 | static int mxt_initialize(struct mxt_data *data) | 1205 | static int mxt_initialize(struct mxt_data *data) |
1107 | { | 1206 | { |
1108 | struct i2c_client *client = data->client; | 1207 | struct i2c_client *client = data->client; |
@@ -1132,11 +1231,9 @@ static int mxt_initialize(struct mxt_data *data) | |||
1132 | goto err_free_object_table; | 1231 | goto err_free_object_table; |
1133 | } | 1232 | } |
1134 | 1233 | ||
1135 | error = mxt_read_t9_resolution(data); | 1234 | error = mxt_initialize_t9_input_device(data); |
1136 | if (error) { | 1235 | if (error) |
1137 | dev_err(&client->dev, "Failed to initialize T9 resolution\n"); | ||
1138 | goto err_free_object_table; | 1236 | goto err_free_object_table; |
1139 | } | ||
1140 | 1237 | ||
1141 | dev_info(&client->dev, | 1238 | dev_info(&client->dev, |
1142 | "Family: %u Variant: %u Firmware V%u.%u.%02X Objects: %u\n", | 1239 | "Family: %u Variant: %u Firmware V%u.%u.%02X Objects: %u\n", |
@@ -1432,40 +1529,26 @@ static void mxt_input_close(struct input_dev *dev) | |||
1432 | static int mxt_probe(struct i2c_client *client, | 1529 | static int mxt_probe(struct i2c_client *client, |
1433 | const struct i2c_device_id *id) | 1530 | const struct i2c_device_id *id) |
1434 | { | 1531 | { |
1435 | const struct mxt_platform_data *pdata = dev_get_platdata(&client->dev); | ||
1436 | struct mxt_data *data; | 1532 | struct mxt_data *data; |
1437 | struct input_dev *input_dev; | 1533 | const struct mxt_platform_data *pdata = dev_get_platdata(&client->dev); |
1438 | int error; | 1534 | int error; |
1439 | unsigned int num_mt_slots; | ||
1440 | unsigned int mt_flags = 0; | ||
1441 | int i; | ||
1442 | 1535 | ||
1443 | if (!pdata) | 1536 | if (!pdata) |
1444 | return -EINVAL; | 1537 | return -EINVAL; |
1445 | 1538 | ||
1446 | data = kzalloc(sizeof(struct mxt_data), GFP_KERNEL); | 1539 | data = kzalloc(sizeof(struct mxt_data), GFP_KERNEL); |
1447 | input_dev = input_allocate_device(); | 1540 | if (!data) { |
1448 | if (!data || !input_dev) { | ||
1449 | dev_err(&client->dev, "Failed to allocate memory\n"); | 1541 | dev_err(&client->dev, "Failed to allocate memory\n"); |
1450 | error = -ENOMEM; | 1542 | return -ENOMEM; |
1451 | goto err_free_mem; | ||
1452 | } | 1543 | } |
1453 | 1544 | ||
1454 | input_dev->name = "Atmel maXTouch Touchscreen"; | ||
1455 | snprintf(data->phys, sizeof(data->phys), "i2c-%u-%04x/input0", | 1545 | snprintf(data->phys, sizeof(data->phys), "i2c-%u-%04x/input0", |
1456 | client->adapter->nr, client->addr); | 1546 | client->adapter->nr, client->addr); |
1457 | 1547 | ||
1458 | input_dev->phys = data->phys; | ||
1459 | |||
1460 | input_dev->id.bustype = BUS_I2C; | ||
1461 | input_dev->dev.parent = &client->dev; | ||
1462 | input_dev->open = mxt_input_open; | ||
1463 | input_dev->close = mxt_input_close; | ||
1464 | |||
1465 | data->client = client; | 1548 | data->client = client; |
1466 | data->input_dev = input_dev; | ||
1467 | data->pdata = pdata; | 1549 | data->pdata = pdata; |
1468 | data->irq = client->irq; | 1550 | data->irq = client->irq; |
1551 | i2c_set_clientdata(client, data); | ||
1469 | 1552 | ||
1470 | init_completion(&data->bl_completion); | 1553 | init_completion(&data->bl_completion); |
1471 | init_completion(&data->reset_completion); | 1554 | init_completion(&data->reset_completion); |
@@ -1481,84 +1564,24 @@ static int mxt_probe(struct i2c_client *client, | |||
1481 | 1564 | ||
1482 | disable_irq(client->irq); | 1565 | disable_irq(client->irq); |
1483 | 1566 | ||
1484 | error = input_register_device(input_dev); | ||
1485 | if (error) { | ||
1486 | dev_err(&client->dev, "Error %d registering input device\n", | ||
1487 | error); | ||
1488 | goto err_free_irq; | ||
1489 | } | ||
1490 | |||
1491 | error = mxt_initialize(data); | 1567 | error = mxt_initialize(data); |
1492 | if (error) | 1568 | if (error) |
1493 | goto err_unregister_device; | 1569 | goto err_free_irq; |
1494 | |||
1495 | __set_bit(EV_ABS, input_dev->evbit); | ||
1496 | __set_bit(EV_KEY, input_dev->evbit); | ||
1497 | __set_bit(BTN_TOUCH, input_dev->keybit); | ||
1498 | |||
1499 | if (pdata->t19_num_keys) { | ||
1500 | __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit); | ||
1501 | |||
1502 | for (i = 0; i < pdata->t19_num_keys; i++) | ||
1503 | if (pdata->t19_keymap[i] != KEY_RESERVED) | ||
1504 | input_set_capability(input_dev, EV_KEY, | ||
1505 | pdata->t19_keymap[i]); | ||
1506 | |||
1507 | mt_flags |= INPUT_MT_POINTER; | ||
1508 | |||
1509 | input_abs_set_res(input_dev, ABS_X, MXT_PIXELS_PER_MM); | ||
1510 | input_abs_set_res(input_dev, ABS_Y, MXT_PIXELS_PER_MM); | ||
1511 | input_abs_set_res(input_dev, ABS_MT_POSITION_X, | ||
1512 | MXT_PIXELS_PER_MM); | ||
1513 | input_abs_set_res(input_dev, ABS_MT_POSITION_Y, | ||
1514 | MXT_PIXELS_PER_MM); | ||
1515 | |||
1516 | input_dev->name = "Atmel maXTouch Touchpad"; | ||
1517 | } | ||
1518 | |||
1519 | /* For single touch */ | ||
1520 | input_set_abs_params(input_dev, ABS_X, | ||
1521 | 0, data->max_x, 0, 0); | ||
1522 | input_set_abs_params(input_dev, ABS_Y, | ||
1523 | 0, data->max_y, 0, 0); | ||
1524 | input_set_abs_params(input_dev, ABS_PRESSURE, | ||
1525 | 0, 255, 0, 0); | ||
1526 | |||
1527 | /* For multi touch */ | ||
1528 | num_mt_slots = data->T9_reportid_max - data->T9_reportid_min + 1; | ||
1529 | error = input_mt_init_slots(input_dev, num_mt_slots, mt_flags); | ||
1530 | if (error) | ||
1531 | goto err_free_object; | ||
1532 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, | ||
1533 | 0, MXT_MAX_AREA, 0, 0); | ||
1534 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | ||
1535 | 0, data->max_x, 0, 0); | ||
1536 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, | ||
1537 | 0, data->max_y, 0, 0); | ||
1538 | input_set_abs_params(input_dev, ABS_MT_PRESSURE, | ||
1539 | 0, 255, 0, 0); | ||
1540 | |||
1541 | input_set_drvdata(input_dev, data); | ||
1542 | i2c_set_clientdata(client, data); | ||
1543 | 1570 | ||
1544 | error = sysfs_create_group(&client->dev.kobj, &mxt_attr_group); | 1571 | error = sysfs_create_group(&client->dev.kobj, &mxt_attr_group); |
1545 | if (error) { | 1572 | if (error) { |
1546 | dev_err(&client->dev, "Failure %d creating sysfs group\n", | 1573 | dev_err(&client->dev, "Failure %d creating sysfs group\n", |
1547 | error); | 1574 | error); |
1548 | goto err_unregister_device; | 1575 | goto err_free_object; |
1549 | } | 1576 | } |
1550 | 1577 | ||
1551 | return 0; | 1578 | return 0; |
1552 | 1579 | ||
1553 | err_unregister_device: | ||
1554 | input_unregister_device(input_dev); | ||
1555 | input_dev = NULL; | ||
1556 | err_free_object: | 1580 | err_free_object: |
1557 | kfree(data->object_table); | 1581 | kfree(data->object_table); |
1558 | err_free_irq: | 1582 | err_free_irq: |
1559 | free_irq(client->irq, data); | 1583 | free_irq(client->irq, data); |
1560 | err_free_mem: | 1584 | err_free_mem: |
1561 | input_free_device(input_dev); | ||
1562 | kfree(data); | 1585 | kfree(data); |
1563 | return error; | 1586 | return error; |
1564 | } | 1587 | } |