diff options
| -rw-r--r-- | drivers/input/touchscreen/atmel_mxt_ts.c | 345 |
1 files changed, 318 insertions, 27 deletions
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 95ee92a91bd2..1b3b845d92f4 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
| 26 | #include <linux/of.h> | 26 | #include <linux/of.h> |
| 27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
| 28 | #include <asm/unaligned.h> | ||
| 28 | 29 | ||
| 29 | /* Version */ | 30 | /* Version */ |
| 30 | #define MXT_VER_20 20 | 31 | #define MXT_VER_20 20 |
| @@ -79,6 +80,7 @@ | |||
| 79 | #define MXT_SPT_DIGITIZER_T43 43 | 80 | #define MXT_SPT_DIGITIZER_T43 43 |
| 80 | #define MXT_SPT_MESSAGECOUNT_T44 44 | 81 | #define MXT_SPT_MESSAGECOUNT_T44 44 |
| 81 | #define MXT_SPT_CTECONFIG_T46 46 | 82 | #define MXT_SPT_CTECONFIG_T46 46 |
| 83 | #define MXT_TOUCH_MULTITOUCHSCREEN_T100 100 | ||
| 82 | 84 | ||
| 83 | /* MXT_GEN_MESSAGE_T5 object */ | 85 | /* MXT_GEN_MESSAGE_T5 object */ |
| 84 | #define MXT_RPTID_NOMSG 0xff | 86 | #define MXT_RPTID_NOMSG 0xff |
| @@ -185,6 +187,36 @@ struct t9_range { | |||
| 185 | #define MXT_RESET_VALUE 0x01 | 187 | #define MXT_RESET_VALUE 0x01 |
| 186 | #define MXT_BACKUP_VALUE 0x55 | 188 | #define MXT_BACKUP_VALUE 0x55 |
| 187 | 189 | ||
| 190 | /* T100 Multiple Touch Touchscreen */ | ||
| 191 | #define MXT_T100_CTRL 0 | ||
| 192 | #define MXT_T100_CFG1 1 | ||
| 193 | #define MXT_T100_TCHAUX 3 | ||
| 194 | #define MXT_T100_XRANGE 13 | ||
| 195 | #define MXT_T100_YRANGE 24 | ||
| 196 | |||
| 197 | #define MXT_T100_CFG_SWITCHXY BIT(5) | ||
| 198 | |||
| 199 | #define MXT_T100_TCHAUX_VECT BIT(0) | ||
| 200 | #define MXT_T100_TCHAUX_AMPL BIT(1) | ||
| 201 | #define MXT_T100_TCHAUX_AREA BIT(2) | ||
| 202 | |||
| 203 | #define MXT_T100_DETECT BIT(7) | ||
| 204 | #define MXT_T100_TYPE_MASK 0x70 | ||
| 205 | |||
| 206 | enum t100_type { | ||
| 207 | MXT_T100_TYPE_FINGER = 1, | ||
| 208 | MXT_T100_TYPE_PASSIVE_STYLUS = 2, | ||
| 209 | MXT_T100_TYPE_HOVERING_FINGER = 4, | ||
| 210 | MXT_T100_TYPE_GLOVE = 5, | ||
| 211 | MXT_T100_TYPE_LARGE_TOUCH = 6, | ||
| 212 | }; | ||
| 213 | |||
| 214 | #define MXT_DISTANCE_ACTIVE_TOUCH 0 | ||
| 215 | #define MXT_DISTANCE_HOVERING 1 | ||
| 216 | |||
| 217 | #define MXT_TOUCH_MAJOR_DEFAULT 1 | ||
| 218 | #define MXT_PRESSURE_DEFAULT 1 | ||
| 219 | |||
| 188 | /* Delay times */ | 220 | /* Delay times */ |
| 189 | #define MXT_BACKUP_TIME 50 /* msec */ | 221 | #define MXT_BACKUP_TIME 50 /* msec */ |
| 190 | #define MXT_RESET_TIME 200 /* msec */ | 222 | #define MXT_RESET_TIME 200 /* msec */ |
| @@ -244,6 +276,9 @@ struct mxt_data { | |||
| 244 | unsigned int max_y; | 276 | unsigned int max_y; |
| 245 | bool in_bootloader; | 277 | bool in_bootloader; |
| 246 | u16 mem_size; | 278 | u16 mem_size; |
| 279 | u8 t100_aux_ampl; | ||
| 280 | u8 t100_aux_area; | ||
| 281 | u8 t100_aux_vect; | ||
| 247 | u8 max_reportid; | 282 | u8 max_reportid; |
| 248 | u32 config_crc; | 283 | u32 config_crc; |
| 249 | u32 info_crc; | 284 | u32 info_crc; |
| @@ -253,6 +288,7 @@ struct mxt_data { | |||
| 253 | bool update_input; | 288 | bool update_input; |
| 254 | u8 last_message_count; | 289 | u8 last_message_count; |
| 255 | u8 num_touchids; | 290 | u8 num_touchids; |
| 291 | u8 multitouch; | ||
| 256 | 292 | ||
| 257 | /* Cached parameters from object table */ | 293 | /* Cached parameters from object table */ |
| 258 | u16 T5_address; | 294 | u16 T5_address; |
| @@ -264,6 +300,8 @@ struct mxt_data { | |||
| 264 | u8 T9_reportid_max; | 300 | u8 T9_reportid_max; |
| 265 | u8 T19_reportid; | 301 | u8 T19_reportid; |
| 266 | u16 T44_address; | 302 | u16 T44_address; |
| 303 | u8 T100_reportid_min; | ||
| 304 | u8 T100_reportid_max; | ||
| 267 | 305 | ||
| 268 | /* for fw update in bootloader */ | 306 | /* for fw update in bootloader */ |
| 269 | struct completion bl_completion; | 307 | struct completion bl_completion; |
| @@ -771,6 +809,114 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 *message) | |||
| 771 | data->update_input = true; | 809 | data->update_input = true; |
| 772 | } | 810 | } |
| 773 | 811 | ||
| 812 | static void mxt_proc_t100_message(struct mxt_data *data, u8 *message) | ||
| 813 | { | ||
| 814 | struct device *dev = &data->client->dev; | ||
| 815 | struct input_dev *input_dev = data->input_dev; | ||
| 816 | int id; | ||
| 817 | u8 status; | ||
| 818 | u8 type = 0; | ||
| 819 | u16 x; | ||
| 820 | u16 y; | ||
| 821 | int distance = 0; | ||
| 822 | int tool = 0; | ||
| 823 | u8 major = 0; | ||
| 824 | u8 pressure = 0; | ||
| 825 | u8 orientation = 0; | ||
| 826 | |||
| 827 | id = message[0] - data->T100_reportid_min - 2; | ||
| 828 | |||
| 829 | /* ignore SCRSTATUS events */ | ||
| 830 | if (id < 0) | ||
| 831 | return; | ||
| 832 | |||
| 833 | status = message[1]; | ||
| 834 | x = get_unaligned_le16(&message[2]); | ||
| 835 | y = get_unaligned_le16(&message[4]); | ||
| 836 | |||
| 837 | if (status & MXT_T100_DETECT) { | ||
| 838 | type = (status & MXT_T100_TYPE_MASK) >> 4; | ||
| 839 | |||
| 840 | switch (type) { | ||
| 841 | case MXT_T100_TYPE_HOVERING_FINGER: | ||
| 842 | tool = MT_TOOL_FINGER; | ||
| 843 | distance = MXT_DISTANCE_HOVERING; | ||
| 844 | |||
| 845 | if (data->t100_aux_vect) | ||
| 846 | orientation = message[data->t100_aux_vect]; | ||
| 847 | |||
| 848 | break; | ||
| 849 | |||
| 850 | case MXT_T100_TYPE_FINGER: | ||
| 851 | case MXT_T100_TYPE_GLOVE: | ||
| 852 | tool = MT_TOOL_FINGER; | ||
| 853 | distance = MXT_DISTANCE_ACTIVE_TOUCH; | ||
| 854 | |||
| 855 | if (data->t100_aux_area) | ||
| 856 | major = message[data->t100_aux_area]; | ||
| 857 | |||
| 858 | if (data->t100_aux_ampl) | ||
| 859 | pressure = message[data->t100_aux_ampl]; | ||
| 860 | |||
| 861 | if (data->t100_aux_vect) | ||
| 862 | orientation = message[data->t100_aux_vect]; | ||
| 863 | |||
| 864 | break; | ||
| 865 | |||
| 866 | case MXT_T100_TYPE_PASSIVE_STYLUS: | ||
| 867 | tool = MT_TOOL_PEN; | ||
| 868 | |||
| 869 | /* | ||
| 870 | * Passive stylus is reported with size zero so | ||
| 871 | * hardcode. | ||
| 872 | */ | ||
| 873 | major = MXT_TOUCH_MAJOR_DEFAULT; | ||
| 874 | |||
| 875 | if (data->t100_aux_ampl) | ||
| 876 | pressure = message[data->t100_aux_ampl]; | ||
| 877 | |||
| 878 | break; | ||
| 879 | |||
| 880 | case MXT_T100_TYPE_LARGE_TOUCH: | ||
| 881 | /* Ignore suppressed touch */ | ||
| 882 | break; | ||
| 883 | |||
| 884 | default: | ||
| 885 | dev_dbg(dev, "Unexpected T100 type\n"); | ||
| 886 | return; | ||
| 887 | } | ||
| 888 | } | ||
| 889 | |||
| 890 | /* | ||
| 891 | * Values reported should be non-zero if tool is touching the | ||
| 892 | * device | ||
| 893 | */ | ||
| 894 | if (!pressure && type != MXT_T100_TYPE_HOVERING_FINGER) | ||
| 895 | pressure = MXT_PRESSURE_DEFAULT; | ||
| 896 | |||
| 897 | input_mt_slot(input_dev, id); | ||
| 898 | |||
| 899 | if (status & MXT_T100_DETECT) { | ||
| 900 | dev_dbg(dev, "[%u] type:%u x:%u y:%u a:%02X p:%02X v:%02X\n", | ||
| 901 | id, type, x, y, major, pressure, orientation); | ||
| 902 | |||
| 903 | input_mt_report_slot_state(input_dev, tool, 1); | ||
| 904 | input_report_abs(input_dev, ABS_MT_POSITION_X, x); | ||
| 905 | input_report_abs(input_dev, ABS_MT_POSITION_Y, y); | ||
| 906 | input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, major); | ||
| 907 | input_report_abs(input_dev, ABS_MT_PRESSURE, pressure); | ||
| 908 | input_report_abs(input_dev, ABS_MT_DISTANCE, distance); | ||
| 909 | input_report_abs(input_dev, ABS_MT_ORIENTATION, orientation); | ||
| 910 | } else { | ||
| 911 | dev_dbg(dev, "[%u] release\n", id); | ||
| 912 | |||
| 913 | /* close out slot */ | ||
| 914 | input_mt_report_slot_state(input_dev, 0, 0); | ||
| 915 | } | ||
| 916 | |||
| 917 | data->update_input = true; | ||
| 918 | } | ||
| 919 | |||
| 774 | static int mxt_proc_message(struct mxt_data *data, u8 *message) | 920 | static int mxt_proc_message(struct mxt_data *data, u8 *message) |
| 775 | { | 921 | { |
| 776 | u8 report_id = message[0]; | 922 | u8 report_id = message[0]; |
| @@ -786,9 +932,12 @@ static int mxt_proc_message(struct mxt_data *data, u8 *message) | |||
| 786 | * is not yet registered. | 932 | * is not yet registered. |
| 787 | */ | 933 | */ |
| 788 | mxt_dump_message(data, message); | 934 | mxt_dump_message(data, message); |
| 789 | } else if (report_id >= data->T9_reportid_min | 935 | } else if (report_id >= data->T9_reportid_min && |
| 790 | && report_id <= data->T9_reportid_max) { | 936 | report_id <= data->T9_reportid_max) { |
| 791 | mxt_proc_t9_message(data, message); | 937 | mxt_proc_t9_message(data, message); |
| 938 | } else if (report_id >= data->T100_reportid_min && | ||
| 939 | report_id <= data->T100_reportid_max) { | ||
| 940 | mxt_proc_t100_message(data, message); | ||
| 792 | } else if (report_id == data->T19_reportid) { | 941 | } else if (report_id == data->T19_reportid) { |
| 793 | mxt_input_button(data, message); | 942 | mxt_input_button(data, message); |
| 794 | data->update_input = true; | 943 | data->update_input = true; |
| @@ -1411,6 +1560,8 @@ static void mxt_free_object_table(struct mxt_data *data) | |||
| 1411 | data->T9_reportid_max = 0; | 1560 | data->T9_reportid_max = 0; |
| 1412 | data->T19_reportid = 0; | 1561 | data->T19_reportid = 0; |
| 1413 | data->T44_address = 0; | 1562 | data->T44_address = 0; |
| 1563 | data->T100_reportid_min = 0; | ||
| 1564 | data->T100_reportid_max = 0; | ||
| 1414 | data->max_reportid = 0; | 1565 | data->max_reportid = 0; |
| 1415 | } | 1566 | } |
| 1416 | 1567 | ||
| @@ -1487,6 +1638,7 @@ static int mxt_get_object_table(struct mxt_data *data) | |||
| 1487 | data->T7_address = object->start_address; | 1638 | data->T7_address = object->start_address; |
| 1488 | break; | 1639 | break; |
| 1489 | case MXT_TOUCH_MULTI_T9: | 1640 | case MXT_TOUCH_MULTI_T9: |
| 1641 | data->multitouch = MXT_TOUCH_MULTI_T9; | ||
| 1490 | data->T9_reportid_min = min_id; | 1642 | data->T9_reportid_min = min_id; |
| 1491 | data->T9_reportid_max = max_id; | 1643 | data->T9_reportid_max = max_id; |
| 1492 | data->num_touchids = object->num_report_ids | 1644 | data->num_touchids = object->num_report_ids |
| @@ -1498,6 +1650,13 @@ static int mxt_get_object_table(struct mxt_data *data) | |||
| 1498 | case MXT_SPT_GPIOPWM_T19: | 1650 | case MXT_SPT_GPIOPWM_T19: |
| 1499 | data->T19_reportid = min_id; | 1651 | data->T19_reportid = min_id; |
| 1500 | break; | 1652 | break; |
| 1653 | case MXT_TOUCH_MULTITOUCHSCREEN_T100: | ||
| 1654 | data->multitouch = MXT_TOUCH_MULTITOUCHSCREEN_T100; | ||
| 1655 | data->T100_reportid_min = min_id; | ||
| 1656 | data->T100_reportid_max = max_id; | ||
| 1657 | /* first two report IDs reserved */ | ||
| 1658 | data->num_touchids = object->num_report_ids - 2; | ||
| 1659 | break; | ||
| 1501 | } | 1660 | } |
| 1502 | 1661 | ||
| 1503 | end_address = object->start_address | 1662 | end_address = object->start_address |
| @@ -1582,10 +1741,88 @@ static int mxt_read_t9_resolution(struct mxt_data *data) | |||
| 1582 | return 0; | 1741 | return 0; |
| 1583 | } | 1742 | } |
| 1584 | 1743 | ||
| 1744 | static int mxt_read_t100_config(struct mxt_data *data) | ||
| 1745 | { | ||
| 1746 | struct i2c_client *client = data->client; | ||
| 1747 | int error; | ||
| 1748 | struct mxt_object *object; | ||
| 1749 | u16 range_x, range_y; | ||
| 1750 | u8 cfg, tchaux; | ||
| 1751 | u8 aux; | ||
| 1752 | |||
| 1753 | object = mxt_get_object(data, MXT_TOUCH_MULTITOUCHSCREEN_T100); | ||
| 1754 | if (!object) | ||
| 1755 | return -EINVAL; | ||
| 1756 | |||
| 1757 | error = __mxt_read_reg(client, | ||
| 1758 | object->start_address + MXT_T100_XRANGE, | ||
| 1759 | sizeof(range_x), &range_x); | ||
| 1760 | if (error) | ||
| 1761 | return error; | ||
| 1762 | |||
| 1763 | le16_to_cpus(&range_x); | ||
| 1764 | |||
| 1765 | error = __mxt_read_reg(client, | ||
| 1766 | object->start_address + MXT_T100_YRANGE, | ||
| 1767 | sizeof(range_y), &range_y); | ||
| 1768 | if (error) | ||
| 1769 | return error; | ||
| 1770 | |||
| 1771 | le16_to_cpus(&range_y); | ||
| 1772 | |||
| 1773 | error = __mxt_read_reg(client, | ||
| 1774 | object->start_address + MXT_T100_CFG1, | ||
| 1775 | 1, &cfg); | ||
| 1776 | if (error) | ||
| 1777 | return error; | ||
| 1778 | |||
| 1779 | error = __mxt_read_reg(client, | ||
| 1780 | object->start_address + MXT_T100_TCHAUX, | ||
| 1781 | 1, &tchaux); | ||
| 1782 | if (error) | ||
| 1783 | return error; | ||
| 1784 | |||
| 1785 | /* Handle default values */ | ||
| 1786 | if (range_x == 0) | ||
| 1787 | range_x = 1023; | ||
| 1788 | |||
| 1789 | if (range_y == 0) | ||
| 1790 | range_y = 1023; | ||
| 1791 | |||
| 1792 | if (cfg & MXT_T100_CFG_SWITCHXY) { | ||
| 1793 | data->max_x = range_y; | ||
| 1794 | data->max_y = range_x; | ||
| 1795 | } else { | ||
| 1796 | data->max_x = range_x; | ||
| 1797 | data->max_y = range_y; | ||
| 1798 | } | ||
| 1799 | |||
| 1800 | /* allocate aux bytes */ | ||
| 1801 | aux = 6; | ||
| 1802 | |||
| 1803 | if (tchaux & MXT_T100_TCHAUX_VECT) | ||
| 1804 | data->t100_aux_vect = aux++; | ||
| 1805 | |||
| 1806 | if (tchaux & MXT_T100_TCHAUX_AMPL) | ||
| 1807 | data->t100_aux_ampl = aux++; | ||
| 1808 | |||
| 1809 | if (tchaux & MXT_T100_TCHAUX_AREA) | ||
| 1810 | data->t100_aux_area = aux++; | ||
| 1811 | |||
| 1812 | dev_dbg(&client->dev, | ||
| 1813 | "T100 aux mappings vect:%u ampl:%u area:%u\n", | ||
| 1814 | data->t100_aux_vect, data->t100_aux_ampl, data->t100_aux_area); | ||
| 1815 | |||
| 1816 | dev_info(&client->dev, | ||
| 1817 | "T100 Touchscreen size X%uY%u\n", data->max_x, data->max_y); | ||
| 1818 | |||
| 1819 | return 0; | ||
| 1820 | } | ||
| 1821 | |||
| 1585 | static int mxt_input_open(struct input_dev *dev); | 1822 | static int mxt_input_open(struct input_dev *dev); |
| 1586 | static void mxt_input_close(struct input_dev *dev); | 1823 | static void mxt_input_close(struct input_dev *dev); |
| 1587 | 1824 | ||
| 1588 | static int mxt_initialize_t9_input_device(struct mxt_data *data) | 1825 | static int mxt_initialize_input_device(struct mxt_data *data) |
| 1589 | { | 1826 | { |
| 1590 | struct device *dev = &data->client->dev; | 1827 | struct device *dev = &data->client->dev; |
| 1591 | const struct mxt_platform_data *pdata = data->pdata; | 1828 | const struct mxt_platform_data *pdata = data->pdata; |
| @@ -1595,9 +1832,25 @@ static int mxt_initialize_t9_input_device(struct mxt_data *data) | |||
| 1595 | unsigned int mt_flags = 0; | 1832 | unsigned int mt_flags = 0; |
| 1596 | int i; | 1833 | int i; |
| 1597 | 1834 | ||
| 1598 | error = mxt_read_t9_resolution(data); | 1835 | switch (data->multitouch) { |
| 1599 | if (error) | 1836 | case MXT_TOUCH_MULTI_T9: |
| 1600 | dev_warn(dev, "Failed to initialize T9 resolution\n"); | 1837 | num_mt_slots = data->T9_reportid_max - data->T9_reportid_min + 1; |
| 1838 | error = mxt_read_t9_resolution(data); | ||
| 1839 | if (error) | ||
| 1840 | dev_warn(dev, "Failed to initialize T9 resolution\n"); | ||
| 1841 | break; | ||
| 1842 | |||
| 1843 | case MXT_TOUCH_MULTITOUCHSCREEN_T100: | ||
| 1844 | num_mt_slots = data->num_touchids; | ||
| 1845 | error = mxt_read_t100_config(data); | ||
| 1846 | if (error) | ||
| 1847 | dev_warn(dev, "Failed to read T100 config\n"); | ||
| 1848 | break; | ||
| 1849 | |||
| 1850 | default: | ||
| 1851 | dev_err(dev, "Invalid multitouch object\n"); | ||
| 1852 | return -EINVAL; | ||
| 1853 | } | ||
| 1601 | 1854 | ||
| 1602 | input_dev = input_allocate_device(); | 1855 | input_dev = input_allocate_device(); |
| 1603 | if (!input_dev) { | 1856 | if (!input_dev) { |
| @@ -1612,9 +1865,7 @@ static int mxt_initialize_t9_input_device(struct mxt_data *data) | |||
| 1612 | input_dev->open = mxt_input_open; | 1865 | input_dev->open = mxt_input_open; |
| 1613 | input_dev->close = mxt_input_close; | 1866 | input_dev->close = mxt_input_close; |
| 1614 | 1867 | ||
| 1615 | __set_bit(EV_ABS, input_dev->evbit); | 1868 | input_set_capability(input_dev, EV_KEY, BTN_TOUCH); |
| 1616 | __set_bit(EV_KEY, input_dev->evbit); | ||
| 1617 | __set_bit(BTN_TOUCH, input_dev->keybit); | ||
| 1618 | 1869 | ||
| 1619 | if (pdata->t19_num_keys) { | 1870 | if (pdata->t19_num_keys) { |
| 1620 | __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit); | 1871 | __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit); |
| @@ -1637,29 +1888,67 @@ static int mxt_initialize_t9_input_device(struct mxt_data *data) | |||
| 1637 | } | 1888 | } |
| 1638 | 1889 | ||
| 1639 | /* For single touch */ | 1890 | /* For single touch */ |
| 1640 | input_set_abs_params(input_dev, ABS_X, | 1891 | input_set_abs_params(input_dev, ABS_X, 0, data->max_x, 0, 0); |
| 1641 | 0, data->max_x, 0, 0); | 1892 | input_set_abs_params(input_dev, ABS_Y, 0, data->max_y, 0, 0); |
| 1642 | input_set_abs_params(input_dev, ABS_Y, | 1893 | |
| 1643 | 0, data->max_y, 0, 0); | 1894 | if (data->multitouch == MXT_TOUCH_MULTI_T9 || |
| 1644 | input_set_abs_params(input_dev, ABS_PRESSURE, | 1895 | (data->multitouch == MXT_TOUCH_MULTITOUCHSCREEN_T100 && |
| 1645 | 0, 255, 0, 0); | 1896 | data->t100_aux_ampl)) { |
| 1897 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, 255, 0, 0); | ||
| 1898 | } | ||
| 1646 | 1899 | ||
| 1647 | /* For multi touch */ | 1900 | /* For multi touch */ |
| 1648 | num_mt_slots = data->T9_reportid_max - data->T9_reportid_min + 1; | ||
| 1649 | error = input_mt_init_slots(input_dev, num_mt_slots, mt_flags); | 1901 | error = input_mt_init_slots(input_dev, num_mt_slots, mt_flags); |
| 1650 | if (error) { | 1902 | if (error) { |
| 1651 | dev_err(dev, "Error %d initialising slots\n", error); | 1903 | dev_err(dev, "Error %d initialising slots\n", error); |
| 1652 | goto err_free_mem; | 1904 | goto err_free_mem; |
| 1653 | } | 1905 | } |
| 1654 | 1906 | ||
| 1655 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, | 1907 | if (data->multitouch == MXT_TOUCH_MULTITOUCHSCREEN_T100) { |
| 1656 | 0, MXT_MAX_AREA, 0, 0); | 1908 | input_set_abs_params(input_dev, ABS_MT_TOOL_TYPE, |
| 1909 | 0, MT_TOOL_MAX, 0, 0); | ||
| 1910 | input_set_abs_params(input_dev, ABS_MT_DISTANCE, | ||
| 1911 | MXT_DISTANCE_ACTIVE_TOUCH, | ||
| 1912 | MXT_DISTANCE_HOVERING, | ||
| 1913 | 0, 0); | ||
| 1914 | } | ||
| 1915 | |||
| 1657 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | 1916 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, |
| 1658 | 0, data->max_x, 0, 0); | 1917 | 0, data->max_x, 0, 0); |
| 1659 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, | 1918 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, |
| 1660 | 0, data->max_y, 0, 0); | 1919 | 0, data->max_y, 0, 0); |
| 1661 | input_set_abs_params(input_dev, ABS_MT_PRESSURE, | 1920 | |
| 1662 | 0, 255, 0, 0); | 1921 | if (data->multitouch == MXT_TOUCH_MULTI_T9 || |
| 1922 | (data->multitouch == MXT_TOUCH_MULTITOUCHSCREEN_T100 && | ||
| 1923 | data->t100_aux_area)) { | ||
| 1924 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, | ||
| 1925 | 0, MXT_MAX_AREA, 0, 0); | ||
| 1926 | } | ||
| 1927 | |||
| 1928 | if (data->multitouch == MXT_TOUCH_MULTI_T9 || | ||
| 1929 | (data->multitouch == MXT_TOUCH_MULTITOUCHSCREEN_T100 && | ||
| 1930 | data->t100_aux_ampl)) { | ||
| 1931 | input_set_abs_params(input_dev, ABS_MT_PRESSURE, | ||
| 1932 | 0, 255, 0, 0); | ||
| 1933 | } | ||
| 1934 | |||
| 1935 | if (data->multitouch == MXT_TOUCH_MULTITOUCHSCREEN_T100 && | ||
| 1936 | data->t100_aux_vect) { | ||
| 1937 | input_set_abs_params(input_dev, ABS_MT_ORIENTATION, | ||
| 1938 | 0, 255, 0, 0); | ||
| 1939 | } | ||
| 1940 | |||
| 1941 | if (data->multitouch == MXT_TOUCH_MULTITOUCHSCREEN_T100 && | ||
| 1942 | data->t100_aux_ampl) { | ||
| 1943 | input_set_abs_params(input_dev, ABS_MT_PRESSURE, | ||
| 1944 | 0, 255, 0, 0); | ||
| 1945 | } | ||
| 1946 | |||
| 1947 | if (data->multitouch == MXT_TOUCH_MULTITOUCHSCREEN_T100 && | ||
| 1948 | data->t100_aux_vect) { | ||
| 1949 | input_set_abs_params(input_dev, ABS_MT_ORIENTATION, | ||
| 1950 | 0, 255, 0, 0); | ||
| 1951 | } | ||
| 1663 | 1952 | ||
| 1664 | input_set_drvdata(input_dev, data); | 1953 | input_set_drvdata(input_dev, data); |
| 1665 | 1954 | ||
| @@ -1765,9 +2054,13 @@ static int mxt_configure_objects(struct mxt_data *data, | |||
| 1765 | dev_warn(dev, "Error %d updating config\n", error); | 2054 | dev_warn(dev, "Error %d updating config\n", error); |
| 1766 | } | 2055 | } |
| 1767 | 2056 | ||
| 1768 | error = mxt_initialize_t9_input_device(data); | 2057 | if (data->multitouch) { |
| 1769 | if (error) | 2058 | error = mxt_initialize_input_device(data); |
| 1770 | return error; | 2059 | if (error) |
| 2060 | return error; | ||
| 2061 | } else { | ||
| 2062 | dev_warn(dev, "No touch object detected\n"); | ||
| 2063 | } | ||
| 1771 | 2064 | ||
| 1772 | dev_info(dev, | 2065 | dev_info(dev, |
| 1773 | "Family: %u Variant: %u Firmware V%u.%u.%02X Objects: %u\n", | 2066 | "Family: %u Variant: %u Firmware V%u.%u.%02X Objects: %u\n", |
| @@ -2044,15 +2337,13 @@ static const struct attribute_group mxt_attr_group = { | |||
| 2044 | static void mxt_start(struct mxt_data *data) | 2337 | static void mxt_start(struct mxt_data *data) |
| 2045 | { | 2338 | { |
| 2046 | /* Touch enable */ | 2339 | /* Touch enable */ |
| 2047 | mxt_write_object(data, | 2340 | mxt_write_object(data, data->multitouch, MXT_TOUCH_CTRL, 0x83); |
| 2048 | MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL, 0x83); | ||
| 2049 | } | 2341 | } |
| 2050 | 2342 | ||
| 2051 | static void mxt_stop(struct mxt_data *data) | 2343 | static void mxt_stop(struct mxt_data *data) |
| 2052 | { | 2344 | { |
| 2053 | /* Touch disable */ | 2345 | /* Touch disable */ |
| 2054 | mxt_write_object(data, | 2346 | mxt_write_object(data, data->multitouch, MXT_TOUCH_CTRL, 0); |
| 2055 | MXT_TOUCH_MULTI_T9, MXT_TOUCH_CTRL, 0); | ||
| 2056 | } | 2347 | } |
| 2057 | 2348 | ||
| 2058 | static int mxt_input_open(struct input_dev *dev) | 2349 | static int mxt_input_open(struct input_dev *dev) |
