diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-05-02 23:34:42 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-05-02 23:34:42 -0400 |
commit | ecd649b3408408841d5793038b0241e55ac7a141 (patch) | |
tree | d328847d78bed378cd53dce8c7f25fb5cfdc6352 | |
parent | 3b6f979319c86d73c48d27deca68331e7924c209 (diff) | |
parent | f6eeb9e548572c0e64632672dbd04363cbdd4eed (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input updates from Dmitry Torokhov:
"Just a few driver fixes"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input:
Input: atmel_mxt_ts - add missing compatible strings to OF device table
Input: atmel_mxt_ts - fix the firmware update
Input: atmel_mxt_ts - add touchpad button mapping for Samsung Chromebook Pro
MAINTAINERS: Rakesh Iyer can't be reached anymore
Input: hideep_ts - fix a typo in Kconfig
Input: alps - fix reporting pressure of v3 trackstick
Input: leds - fix out of bound access
Input: synaptics-rmi4 - fix an unchecked out of memory error path
-rw-r--r-- | Documentation/devicetree/bindings/input/atmel,maxtouch.txt | 7 | ||||
-rw-r--r-- | MAINTAINERS | 1 | ||||
-rw-r--r-- | drivers/input/input-leds.c | 8 | ||||
-rw-r--r-- | drivers/input/mouse/alps.c | 2 | ||||
-rw-r--r-- | drivers/input/rmi4/rmi_spi.c | 7 | ||||
-rw-r--r-- | drivers/input/touchscreen/Kconfig | 2 | ||||
-rw-r--r-- | drivers/input/touchscreen/atmel_mxt_ts.c | 200 |
7 files changed, 142 insertions, 85 deletions
diff --git a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt index 23e3abc3fdef..c88919480d37 100644 --- a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt +++ b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt | |||
@@ -4,6 +4,13 @@ Required properties: | |||
4 | - compatible: | 4 | - compatible: |
5 | atmel,maxtouch | 5 | atmel,maxtouch |
6 | 6 | ||
7 | The following compatibles have been used in various products but are | ||
8 | deprecated: | ||
9 | atmel,qt602240_ts | ||
10 | atmel,atmel_mxt_ts | ||
11 | atmel,atmel_mxt_tp | ||
12 | atmel,mXT224 | ||
13 | |||
7 | - reg: The I2C address of the device | 14 | - reg: The I2C address of the device |
8 | 15 | ||
9 | - interrupts: The sink for the touchpad's IRQ output | 16 | - interrupts: The sink for the touchpad's IRQ output |
diff --git a/MAINTAINERS b/MAINTAINERS index 79bb02ff812f..eab763f17aab 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -13853,7 +13853,6 @@ S: Supported | |||
13853 | F: drivers/iommu/tegra* | 13853 | F: drivers/iommu/tegra* |
13854 | 13854 | ||
13855 | TEGRA KBC DRIVER | 13855 | TEGRA KBC DRIVER |
13856 | M: Rakesh Iyer <riyer@nvidia.com> | ||
13857 | M: Laxman Dewangan <ldewangan@nvidia.com> | 13856 | M: Laxman Dewangan <ldewangan@nvidia.com> |
13858 | S: Supported | 13857 | S: Supported |
13859 | F: drivers/input/keyboard/tegra-kbc.c | 13858 | F: drivers/input/keyboard/tegra-kbc.c |
diff --git a/drivers/input/input-leds.c b/drivers/input/input-leds.c index 766bf2660116..5f04b2d94635 100644 --- a/drivers/input/input-leds.c +++ b/drivers/input/input-leds.c | |||
@@ -88,6 +88,7 @@ static int input_leds_connect(struct input_handler *handler, | |||
88 | const struct input_device_id *id) | 88 | const struct input_device_id *id) |
89 | { | 89 | { |
90 | struct input_leds *leds; | 90 | struct input_leds *leds; |
91 | struct input_led *led; | ||
91 | unsigned int num_leds; | 92 | unsigned int num_leds; |
92 | unsigned int led_code; | 93 | unsigned int led_code; |
93 | int led_no; | 94 | int led_no; |
@@ -119,14 +120,13 @@ static int input_leds_connect(struct input_handler *handler, | |||
119 | 120 | ||
120 | led_no = 0; | 121 | led_no = 0; |
121 | for_each_set_bit(led_code, dev->ledbit, LED_CNT) { | 122 | for_each_set_bit(led_code, dev->ledbit, LED_CNT) { |
122 | struct input_led *led = &leds->leds[led_no]; | 123 | if (!input_led_info[led_code].name) |
124 | continue; | ||
123 | 125 | ||
126 | led = &leds->leds[led_no]; | ||
124 | led->handle = &leds->handle; | 127 | led->handle = &leds->handle; |
125 | led->code = led_code; | 128 | led->code = led_code; |
126 | 129 | ||
127 | if (!input_led_info[led_code].name) | ||
128 | continue; | ||
129 | |||
130 | led->cdev.name = kasprintf(GFP_KERNEL, "%s::%s", | 130 | led->cdev.name = kasprintf(GFP_KERNEL, "%s::%s", |
131 | dev_name(&dev->dev), | 131 | dev_name(&dev->dev), |
132 | input_led_info[led_code].name); | 132 | input_led_info[led_code].name); |
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 0a67f235ba88..38f9501acdf0 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -583,7 +583,7 @@ static void alps_process_trackstick_packet_v3(struct psmouse *psmouse) | |||
583 | 583 | ||
584 | x = (s8)(((packet[0] & 0x20) << 2) | (packet[1] & 0x7f)); | 584 | x = (s8)(((packet[0] & 0x20) << 2) | (packet[1] & 0x7f)); |
585 | y = (s8)(((packet[0] & 0x10) << 3) | (packet[2] & 0x7f)); | 585 | y = (s8)(((packet[0] & 0x10) << 3) | (packet[2] & 0x7f)); |
586 | z = packet[4] & 0x7c; | 586 | z = packet[4] & 0x7f; |
587 | 587 | ||
588 | /* | 588 | /* |
589 | * The x and y values tend to be quite large, and when used | 589 | * The x and y values tend to be quite large, and when used |
diff --git a/drivers/input/rmi4/rmi_spi.c b/drivers/input/rmi4/rmi_spi.c index 76edbf2c1bce..082defc329a8 100644 --- a/drivers/input/rmi4/rmi_spi.c +++ b/drivers/input/rmi4/rmi_spi.c | |||
@@ -147,8 +147,11 @@ static int rmi_spi_xfer(struct rmi_spi_xport *rmi_spi, | |||
147 | if (len > RMI_SPI_XFER_SIZE_LIMIT) | 147 | if (len > RMI_SPI_XFER_SIZE_LIMIT) |
148 | return -EINVAL; | 148 | return -EINVAL; |
149 | 149 | ||
150 | if (rmi_spi->xfer_buf_size < len) | 150 | if (rmi_spi->xfer_buf_size < len) { |
151 | rmi_spi_manage_pools(rmi_spi, len); | 151 | ret = rmi_spi_manage_pools(rmi_spi, len); |
152 | if (ret < 0) | ||
153 | return ret; | ||
154 | } | ||
152 | 155 | ||
153 | if (addr == 0) | 156 | if (addr == 0) |
154 | /* | 157 | /* |
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 4f15496fec8b..3e613afa10b4 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig | |||
@@ -362,7 +362,7 @@ config TOUCHSCREEN_HIDEEP | |||
362 | 362 | ||
363 | If unsure, say N. | 363 | If unsure, say N. |
364 | 364 | ||
365 | To compile this driver as a moudle, choose M here : the | 365 | To compile this driver as a module, choose M here : the |
366 | module will be called hideep_ts. | 366 | module will be called hideep_ts. |
367 | 367 | ||
368 | config TOUCHSCREEN_ILI210X | 368 | config TOUCHSCREEN_ILI210X |
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 5d9699fe1b55..09194721aed2 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c | |||
@@ -280,7 +280,8 @@ struct mxt_data { | |||
280 | struct input_dev *input_dev; | 280 | struct input_dev *input_dev; |
281 | char phys[64]; /* device physical location */ | 281 | char phys[64]; /* device physical location */ |
282 | struct mxt_object *object_table; | 282 | struct mxt_object *object_table; |
283 | struct mxt_info info; | 283 | struct mxt_info *info; |
284 | void *raw_info_block; | ||
284 | unsigned int irq; | 285 | unsigned int irq; |
285 | unsigned int max_x; | 286 | unsigned int max_x; |
286 | unsigned int max_y; | 287 | unsigned int max_y; |
@@ -460,12 +461,13 @@ static int mxt_lookup_bootloader_address(struct mxt_data *data, bool retry) | |||
460 | { | 461 | { |
461 | u8 appmode = data->client->addr; | 462 | u8 appmode = data->client->addr; |
462 | u8 bootloader; | 463 | u8 bootloader; |
464 | u8 family_id = data->info ? data->info->family_id : 0; | ||
463 | 465 | ||
464 | switch (appmode) { | 466 | switch (appmode) { |
465 | case 0x4a: | 467 | case 0x4a: |
466 | case 0x4b: | 468 | case 0x4b: |
467 | /* Chips after 1664S use different scheme */ | 469 | /* Chips after 1664S use different scheme */ |
468 | if (retry || data->info.family_id >= 0xa2) { | 470 | if (retry || family_id >= 0xa2) { |
469 | bootloader = appmode - 0x24; | 471 | bootloader = appmode - 0x24; |
470 | break; | 472 | break; |
471 | } | 473 | } |
@@ -692,7 +694,7 @@ mxt_get_object(struct mxt_data *data, u8 type) | |||
692 | struct mxt_object *object; | 694 | struct mxt_object *object; |
693 | int i; | 695 | int i; |
694 | 696 | ||
695 | for (i = 0; i < data->info.object_num; i++) { | 697 | for (i = 0; i < data->info->object_num; i++) { |
696 | object = data->object_table + i; | 698 | object = data->object_table + i; |
697 | if (object->type == type) | 699 | if (object->type == type) |
698 | return object; | 700 | return object; |
@@ -1462,12 +1464,12 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg) | |||
1462 | data_pos += offset; | 1464 | data_pos += offset; |
1463 | } | 1465 | } |
1464 | 1466 | ||
1465 | if (cfg_info.family_id != data->info.family_id) { | 1467 | if (cfg_info.family_id != data->info->family_id) { |
1466 | dev_err(dev, "Family ID mismatch!\n"); | 1468 | dev_err(dev, "Family ID mismatch!\n"); |
1467 | return -EINVAL; | 1469 | return -EINVAL; |
1468 | } | 1470 | } |
1469 | 1471 | ||
1470 | if (cfg_info.variant_id != data->info.variant_id) { | 1472 | if (cfg_info.variant_id != data->info->variant_id) { |
1471 | dev_err(dev, "Variant ID mismatch!\n"); | 1473 | dev_err(dev, "Variant ID mismatch!\n"); |
1472 | return -EINVAL; | 1474 | return -EINVAL; |
1473 | } | 1475 | } |
@@ -1512,7 +1514,7 @@ static int mxt_update_cfg(struct mxt_data *data, const struct firmware *cfg) | |||
1512 | 1514 | ||
1513 | /* Malloc memory to store configuration */ | 1515 | /* Malloc memory to store configuration */ |
1514 | cfg_start_ofs = MXT_OBJECT_START + | 1516 | cfg_start_ofs = MXT_OBJECT_START + |
1515 | data->info.object_num * sizeof(struct mxt_object) + | 1517 | data->info->object_num * sizeof(struct mxt_object) + |
1516 | MXT_INFO_CHECKSUM_SIZE; | 1518 | MXT_INFO_CHECKSUM_SIZE; |
1517 | config_mem_size = data->mem_size - cfg_start_ofs; | 1519 | config_mem_size = data->mem_size - cfg_start_ofs; |
1518 | config_mem = kzalloc(config_mem_size, GFP_KERNEL); | 1520 | config_mem = kzalloc(config_mem_size, GFP_KERNEL); |
@@ -1563,20 +1565,6 @@ release_mem: | |||
1563 | return ret; | 1565 | return ret; |
1564 | } | 1566 | } |
1565 | 1567 | ||
1566 | static int mxt_get_info(struct mxt_data *data) | ||
1567 | { | ||
1568 | struct i2c_client *client = data->client; | ||
1569 | struct mxt_info *info = &data->info; | ||
1570 | int error; | ||
1571 | |||
1572 | /* Read 7-byte info block starting at address 0 */ | ||
1573 | error = __mxt_read_reg(client, 0, sizeof(*info), info); | ||
1574 | if (error) | ||
1575 | return error; | ||
1576 | |||
1577 | return 0; | ||
1578 | } | ||
1579 | |||
1580 | static void mxt_free_input_device(struct mxt_data *data) | 1568 | static void mxt_free_input_device(struct mxt_data *data) |
1581 | { | 1569 | { |
1582 | if (data->input_dev) { | 1570 | if (data->input_dev) { |
@@ -1591,9 +1579,10 @@ static void mxt_free_object_table(struct mxt_data *data) | |||
1591 | video_unregister_device(&data->dbg.vdev); | 1579 | video_unregister_device(&data->dbg.vdev); |
1592 | v4l2_device_unregister(&data->dbg.v4l2); | 1580 | v4l2_device_unregister(&data->dbg.v4l2); |
1593 | #endif | 1581 | #endif |
1594 | |||
1595 | kfree(data->object_table); | ||
1596 | data->object_table = NULL; | 1582 | data->object_table = NULL; |
1583 | data->info = NULL; | ||
1584 | kfree(data->raw_info_block); | ||
1585 | data->raw_info_block = NULL; | ||
1597 | kfree(data->msg_buf); | 1586 | kfree(data->msg_buf); |
1598 | data->msg_buf = NULL; | 1587 | data->msg_buf = NULL; |
1599 | data->T5_address = 0; | 1588 | data->T5_address = 0; |
@@ -1609,34 +1598,18 @@ static void mxt_free_object_table(struct mxt_data *data) | |||
1609 | data->max_reportid = 0; | 1598 | data->max_reportid = 0; |
1610 | } | 1599 | } |
1611 | 1600 | ||
1612 | static int mxt_get_object_table(struct mxt_data *data) | 1601 | static int mxt_parse_object_table(struct mxt_data *data, |
1602 | struct mxt_object *object_table) | ||
1613 | { | 1603 | { |
1614 | struct i2c_client *client = data->client; | 1604 | struct i2c_client *client = data->client; |
1615 | size_t table_size; | ||
1616 | struct mxt_object *object_table; | ||
1617 | int error; | ||
1618 | int i; | 1605 | int i; |
1619 | u8 reportid; | 1606 | u8 reportid; |
1620 | u16 end_address; | 1607 | u16 end_address; |
1621 | 1608 | ||
1622 | table_size = data->info.object_num * sizeof(struct mxt_object); | ||
1623 | object_table = kzalloc(table_size, GFP_KERNEL); | ||
1624 | if (!object_table) { | ||
1625 | dev_err(&data->client->dev, "Failed to allocate memory\n"); | ||
1626 | return -ENOMEM; | ||
1627 | } | ||
1628 | |||
1629 | error = __mxt_read_reg(client, MXT_OBJECT_START, table_size, | ||
1630 | object_table); | ||
1631 | if (error) { | ||
1632 | kfree(object_table); | ||
1633 | return error; | ||
1634 | } | ||
1635 | |||
1636 | /* Valid Report IDs start counting from 1 */ | 1609 | /* Valid Report IDs start counting from 1 */ |
1637 | reportid = 1; | 1610 | reportid = 1; |
1638 | data->mem_size = 0; | 1611 | data->mem_size = 0; |
1639 | for (i = 0; i < data->info.object_num; i++) { | 1612 | for (i = 0; i < data->info->object_num; i++) { |
1640 | struct mxt_object *object = object_table + i; | 1613 | struct mxt_object *object = object_table + i; |
1641 | u8 min_id, max_id; | 1614 | u8 min_id, max_id; |
1642 | 1615 | ||
@@ -1660,8 +1633,8 @@ static int mxt_get_object_table(struct mxt_data *data) | |||
1660 | 1633 | ||
1661 | switch (object->type) { | 1634 | switch (object->type) { |
1662 | case MXT_GEN_MESSAGE_T5: | 1635 | case MXT_GEN_MESSAGE_T5: |
1663 | if (data->info.family_id == 0x80 && | 1636 | if (data->info->family_id == 0x80 && |
1664 | data->info.version < 0x20) { | 1637 | data->info->version < 0x20) { |
1665 | /* | 1638 | /* |
1666 | * On mXT224 firmware versions prior to V2.0 | 1639 | * On mXT224 firmware versions prior to V2.0 |
1667 | * read and discard unused CRC byte otherwise | 1640 | * read and discard unused CRC byte otherwise |
@@ -1716,24 +1689,102 @@ static int mxt_get_object_table(struct mxt_data *data) | |||
1716 | /* If T44 exists, T5 position has to be directly after */ | 1689 | /* If T44 exists, T5 position has to be directly after */ |
1717 | if (data->T44_address && (data->T5_address != data->T44_address + 1)) { | 1690 | if (data->T44_address && (data->T5_address != data->T44_address + 1)) { |
1718 | dev_err(&client->dev, "Invalid T44 position\n"); | 1691 | dev_err(&client->dev, "Invalid T44 position\n"); |
1719 | error = -EINVAL; | 1692 | return -EINVAL; |
1720 | goto free_object_table; | ||
1721 | } | 1693 | } |
1722 | 1694 | ||
1723 | data->msg_buf = kcalloc(data->max_reportid, | 1695 | data->msg_buf = kcalloc(data->max_reportid, |
1724 | data->T5_msg_size, GFP_KERNEL); | 1696 | data->T5_msg_size, GFP_KERNEL); |
1725 | if (!data->msg_buf) { | 1697 | if (!data->msg_buf) |
1726 | dev_err(&client->dev, "Failed to allocate message buffer\n"); | 1698 | return -ENOMEM; |
1699 | |||
1700 | return 0; | ||
1701 | } | ||
1702 | |||
1703 | static int mxt_read_info_block(struct mxt_data *data) | ||
1704 | { | ||
1705 | struct i2c_client *client = data->client; | ||
1706 | int error; | ||
1707 | size_t size; | ||
1708 | void *id_buf, *buf; | ||
1709 | uint8_t num_objects; | ||
1710 | u32 calculated_crc; | ||
1711 | u8 *crc_ptr; | ||
1712 | |||
1713 | /* If info block already allocated, free it */ | ||
1714 | if (data->raw_info_block) | ||
1715 | mxt_free_object_table(data); | ||
1716 | |||
1717 | /* Read 7-byte ID information block starting at address 0 */ | ||
1718 | size = sizeof(struct mxt_info); | ||
1719 | id_buf = kzalloc(size, GFP_KERNEL); | ||
1720 | if (!id_buf) | ||
1721 | return -ENOMEM; | ||
1722 | |||
1723 | error = __mxt_read_reg(client, 0, size, id_buf); | ||
1724 | if (error) | ||
1725 | goto err_free_mem; | ||
1726 | |||
1727 | /* Resize buffer to give space for rest of info block */ | ||
1728 | num_objects = ((struct mxt_info *)id_buf)->object_num; | ||
1729 | size += (num_objects * sizeof(struct mxt_object)) | ||
1730 | + MXT_INFO_CHECKSUM_SIZE; | ||
1731 | |||
1732 | buf = krealloc(id_buf, size, GFP_KERNEL); | ||
1733 | if (!buf) { | ||
1727 | error = -ENOMEM; | 1734 | error = -ENOMEM; |
1728 | goto free_object_table; | 1735 | goto err_free_mem; |
1736 | } | ||
1737 | id_buf = buf; | ||
1738 | |||
1739 | /* Read rest of info block */ | ||
1740 | error = __mxt_read_reg(client, MXT_OBJECT_START, | ||
1741 | size - MXT_OBJECT_START, | ||
1742 | id_buf + MXT_OBJECT_START); | ||
1743 | if (error) | ||
1744 | goto err_free_mem; | ||
1745 | |||
1746 | /* Extract & calculate checksum */ | ||
1747 | crc_ptr = id_buf + size - MXT_INFO_CHECKSUM_SIZE; | ||
1748 | data->info_crc = crc_ptr[0] | (crc_ptr[1] << 8) | (crc_ptr[2] << 16); | ||
1749 | |||
1750 | calculated_crc = mxt_calculate_crc(id_buf, 0, | ||
1751 | size - MXT_INFO_CHECKSUM_SIZE); | ||
1752 | |||
1753 | /* | ||
1754 | * CRC mismatch can be caused by data corruption due to I2C comms | ||
1755 | * issue or else device is not using Object Based Protocol (eg i2c-hid) | ||
1756 | */ | ||
1757 | if ((data->info_crc == 0) || (data->info_crc != calculated_crc)) { | ||
1758 | dev_err(&client->dev, | ||
1759 | "Info Block CRC error calculated=0x%06X read=0x%06X\n", | ||
1760 | calculated_crc, data->info_crc); | ||
1761 | error = -EIO; | ||
1762 | goto err_free_mem; | ||
1763 | } | ||
1764 | |||
1765 | data->raw_info_block = id_buf; | ||
1766 | data->info = (struct mxt_info *)id_buf; | ||
1767 | |||
1768 | dev_info(&client->dev, | ||
1769 | "Family: %u Variant: %u Firmware V%u.%u.%02X Objects: %u\n", | ||
1770 | data->info->family_id, data->info->variant_id, | ||
1771 | data->info->version >> 4, data->info->version & 0xf, | ||
1772 | data->info->build, data->info->object_num); | ||
1773 | |||
1774 | /* Parse object table information */ | ||
1775 | error = mxt_parse_object_table(data, id_buf + MXT_OBJECT_START); | ||
1776 | if (error) { | ||
1777 | dev_err(&client->dev, "Error %d parsing object table\n", error); | ||
1778 | mxt_free_object_table(data); | ||
1779 | goto err_free_mem; | ||
1729 | } | 1780 | } |
1730 | 1781 | ||
1731 | data->object_table = object_table; | 1782 | data->object_table = (struct mxt_object *)(id_buf + MXT_OBJECT_START); |
1732 | 1783 | ||
1733 | return 0; | 1784 | return 0; |
1734 | 1785 | ||
1735 | free_object_table: | 1786 | err_free_mem: |
1736 | mxt_free_object_table(data); | 1787 | kfree(id_buf); |
1737 | return error; | 1788 | return error; |
1738 | } | 1789 | } |
1739 | 1790 | ||
@@ -2046,7 +2097,7 @@ static int mxt_initialize(struct mxt_data *data) | |||
2046 | int error; | 2097 | int error; |
2047 | 2098 | ||
2048 | while (1) { | 2099 | while (1) { |
2049 | error = mxt_get_info(data); | 2100 | error = mxt_read_info_block(data); |
2050 | if (!error) | 2101 | if (!error) |
2051 | break; | 2102 | break; |
2052 | 2103 | ||
@@ -2077,16 +2128,9 @@ static int mxt_initialize(struct mxt_data *data) | |||
2077 | msleep(MXT_FW_RESET_TIME); | 2128 | msleep(MXT_FW_RESET_TIME); |
2078 | } | 2129 | } |
2079 | 2130 | ||
2080 | /* Get object table information */ | ||
2081 | error = mxt_get_object_table(data); | ||
2082 | if (error) { | ||
2083 | dev_err(&client->dev, "Error %d reading object table\n", error); | ||
2084 | return error; | ||
2085 | } | ||
2086 | |||
2087 | error = mxt_acquire_irq(data); | 2131 | error = mxt_acquire_irq(data); |
2088 | if (error) | 2132 | if (error) |
2089 | goto err_free_object_table; | 2133 | return error; |
2090 | 2134 | ||
2091 | error = request_firmware_nowait(THIS_MODULE, true, MXT_CFG_NAME, | 2135 | error = request_firmware_nowait(THIS_MODULE, true, MXT_CFG_NAME, |
2092 | &client->dev, GFP_KERNEL, data, | 2136 | &client->dev, GFP_KERNEL, data, |
@@ -2094,14 +2138,10 @@ static int mxt_initialize(struct mxt_data *data) | |||
2094 | if (error) { | 2138 | if (error) { |
2095 | dev_err(&client->dev, "Failed to invoke firmware loader: %d\n", | 2139 | dev_err(&client->dev, "Failed to invoke firmware loader: %d\n", |
2096 | error); | 2140 | error); |
2097 | goto err_free_object_table; | 2141 | return error; |
2098 | } | 2142 | } |
2099 | 2143 | ||
2100 | return 0; | 2144 | return 0; |
2101 | |||
2102 | err_free_object_table: | ||
2103 | mxt_free_object_table(data); | ||
2104 | return error; | ||
2105 | } | 2145 | } |
2106 | 2146 | ||
2107 | static int mxt_set_t7_power_cfg(struct mxt_data *data, u8 sleep) | 2147 | static int mxt_set_t7_power_cfg(struct mxt_data *data, u8 sleep) |
@@ -2162,7 +2202,7 @@ recheck: | |||
2162 | static u16 mxt_get_debug_value(struct mxt_data *data, unsigned int x, | 2202 | static u16 mxt_get_debug_value(struct mxt_data *data, unsigned int x, |
2163 | unsigned int y) | 2203 | unsigned int y) |
2164 | { | 2204 | { |
2165 | struct mxt_info *info = &data->info; | 2205 | struct mxt_info *info = data->info; |
2166 | struct mxt_dbg *dbg = &data->dbg; | 2206 | struct mxt_dbg *dbg = &data->dbg; |
2167 | unsigned int ofs, page; | 2207 | unsigned int ofs, page; |
2168 | unsigned int col = 0; | 2208 | unsigned int col = 0; |
@@ -2490,7 +2530,7 @@ static const struct video_device mxt_video_device = { | |||
2490 | 2530 | ||
2491 | static void mxt_debug_init(struct mxt_data *data) | 2531 | static void mxt_debug_init(struct mxt_data *data) |
2492 | { | 2532 | { |
2493 | struct mxt_info *info = &data->info; | 2533 | struct mxt_info *info = data->info; |
2494 | struct mxt_dbg *dbg = &data->dbg; | 2534 | struct mxt_dbg *dbg = &data->dbg; |
2495 | struct mxt_object *object; | 2535 | struct mxt_object *object; |
2496 | int error; | 2536 | int error; |
@@ -2576,7 +2616,6 @@ static int mxt_configure_objects(struct mxt_data *data, | |||
2576 | const struct firmware *cfg) | 2616 | const struct firmware *cfg) |
2577 | { | 2617 | { |
2578 | struct device *dev = &data->client->dev; | 2618 | struct device *dev = &data->client->dev; |
2579 | struct mxt_info *info = &data->info; | ||
2580 | int error; | 2619 | int error; |
2581 | 2620 | ||
2582 | error = mxt_init_t7_power_cfg(data); | 2621 | error = mxt_init_t7_power_cfg(data); |
@@ -2601,11 +2640,6 @@ static int mxt_configure_objects(struct mxt_data *data, | |||
2601 | 2640 | ||
2602 | mxt_debug_init(data); | 2641 | mxt_debug_init(data); |
2603 | 2642 | ||
2604 | dev_info(dev, | ||
2605 | "Family: %u Variant: %u Firmware V%u.%u.%02X Objects: %u\n", | ||
2606 | info->family_id, info->variant_id, info->version >> 4, | ||
2607 | info->version & 0xf, info->build, info->object_num); | ||
2608 | |||
2609 | return 0; | 2643 | return 0; |
2610 | } | 2644 | } |
2611 | 2645 | ||
@@ -2614,7 +2648,7 @@ static ssize_t mxt_fw_version_show(struct device *dev, | |||
2614 | struct device_attribute *attr, char *buf) | 2648 | struct device_attribute *attr, char *buf) |
2615 | { | 2649 | { |
2616 | struct mxt_data *data = dev_get_drvdata(dev); | 2650 | struct mxt_data *data = dev_get_drvdata(dev); |
2617 | struct mxt_info *info = &data->info; | 2651 | struct mxt_info *info = data->info; |
2618 | return scnprintf(buf, PAGE_SIZE, "%u.%u.%02X\n", | 2652 | return scnprintf(buf, PAGE_SIZE, "%u.%u.%02X\n", |
2619 | info->version >> 4, info->version & 0xf, info->build); | 2653 | info->version >> 4, info->version & 0xf, info->build); |
2620 | } | 2654 | } |
@@ -2624,7 +2658,7 @@ static ssize_t mxt_hw_version_show(struct device *dev, | |||
2624 | struct device_attribute *attr, char *buf) | 2658 | struct device_attribute *attr, char *buf) |
2625 | { | 2659 | { |
2626 | struct mxt_data *data = dev_get_drvdata(dev); | 2660 | struct mxt_data *data = dev_get_drvdata(dev); |
2627 | struct mxt_info *info = &data->info; | 2661 | struct mxt_info *info = data->info; |
2628 | return scnprintf(buf, PAGE_SIZE, "%u.%u\n", | 2662 | return scnprintf(buf, PAGE_SIZE, "%u.%u\n", |
2629 | info->family_id, info->variant_id); | 2663 | info->family_id, info->variant_id); |
2630 | } | 2664 | } |
@@ -2663,7 +2697,7 @@ static ssize_t mxt_object_show(struct device *dev, | |||
2663 | return -ENOMEM; | 2697 | return -ENOMEM; |
2664 | 2698 | ||
2665 | error = 0; | 2699 | error = 0; |
2666 | for (i = 0; i < data->info.object_num; i++) { | 2700 | for (i = 0; i < data->info->object_num; i++) { |
2667 | object = data->object_table + i; | 2701 | object = data->object_table + i; |
2668 | 2702 | ||
2669 | if (!mxt_object_readable(object->type)) | 2703 | if (!mxt_object_readable(object->type)) |
@@ -3035,6 +3069,15 @@ static const struct dmi_system_id mxt_dmi_table[] = { | |||
3035 | .driver_data = samus_platform_data, | 3069 | .driver_data = samus_platform_data, |
3036 | }, | 3070 | }, |
3037 | { | 3071 | { |
3072 | /* Samsung Chromebook Pro */ | ||
3073 | .ident = "Samsung Chromebook Pro", | ||
3074 | .matches = { | ||
3075 | DMI_MATCH(DMI_SYS_VENDOR, "Google"), | ||
3076 | DMI_MATCH(DMI_PRODUCT_NAME, "Caroline"), | ||
3077 | }, | ||
3078 | .driver_data = samus_platform_data, | ||
3079 | }, | ||
3080 | { | ||
3038 | /* Other Google Chromebooks */ | 3081 | /* Other Google Chromebooks */ |
3039 | .ident = "Chromebook", | 3082 | .ident = "Chromebook", |
3040 | .matches = { | 3083 | .matches = { |
@@ -3254,6 +3297,11 @@ static SIMPLE_DEV_PM_OPS(mxt_pm_ops, mxt_suspend, mxt_resume); | |||
3254 | 3297 | ||
3255 | static const struct of_device_id mxt_of_match[] = { | 3298 | static const struct of_device_id mxt_of_match[] = { |
3256 | { .compatible = "atmel,maxtouch", }, | 3299 | { .compatible = "atmel,maxtouch", }, |
3300 | /* Compatibles listed below are deprecated */ | ||
3301 | { .compatible = "atmel,qt602240_ts", }, | ||
3302 | { .compatible = "atmel,atmel_mxt_ts", }, | ||
3303 | { .compatible = "atmel,atmel_mxt_tp", }, | ||
3304 | { .compatible = "atmel,mXT224", }, | ||
3257 | {}, | 3305 | {}, |
3258 | }; | 3306 | }; |
3259 | MODULE_DEVICE_TABLE(of, mxt_of_match); | 3307 | MODULE_DEVICE_TABLE(of, mxt_of_match); |