|
9 | 9 | */ |
10 | 10 |
|
11 | 11 | #include <linux/acpi.h> |
| 12 | +#include <linux/ctype.h> |
12 | 13 | #include <linux/device.h> |
13 | 14 | #include <linux/dmi.h> |
14 | 15 | #include <linux/efi_embedded_fw.h> |
15 | 16 | #include <linux/i2c.h> |
| 17 | +#include <linux/init.h> |
| 18 | +#include <linux/kstrtox.h> |
16 | 19 | #include <linux/notifier.h> |
17 | 20 | #include <linux/property.h> |
18 | 21 | #include <linux/string.h> |
@@ -897,6 +900,22 @@ static const struct ts_dmi_data schneider_sct101ctm_data = { |
897 | 900 | .properties = schneider_sct101ctm_props, |
898 | 901 | }; |
899 | 902 |
|
| 903 | +static const struct property_entry globalspace_solt_ivw116_props[] = { |
| 904 | + PROPERTY_ENTRY_U32("touchscreen-min-x", 7), |
| 905 | + PROPERTY_ENTRY_U32("touchscreen-min-y", 22), |
| 906 | + PROPERTY_ENTRY_U32("touchscreen-size-x", 1723), |
| 907 | + PROPERTY_ENTRY_U32("touchscreen-size-y", 1077), |
| 908 | + PROPERTY_ENTRY_STRING("firmware-name", "gsl1680-globalspace-solt-ivw116.fw"), |
| 909 | + PROPERTY_ENTRY_U32("silead,max-fingers", 10), |
| 910 | + PROPERTY_ENTRY_BOOL("silead,home-button"), |
| 911 | + { } |
| 912 | +}; |
| 913 | + |
| 914 | +static const struct ts_dmi_data globalspace_solt_ivw116_data = { |
| 915 | + .acpi_name = "MSSL1680:00", |
| 916 | + .properties = globalspace_solt_ivw116_props, |
| 917 | +}; |
| 918 | + |
900 | 919 | static const struct property_entry techbite_arc_11_6_props[] = { |
901 | 920 | PROPERTY_ENTRY_U32("touchscreen-min-x", 5), |
902 | 921 | PROPERTY_ENTRY_U32("touchscreen-min-y", 7), |
@@ -1385,6 +1404,17 @@ const struct dmi_system_id touchscreen_dmi_table[] = { |
1385 | 1404 | DMI_MATCH(DMI_BIOS_DATE, "04/24/2018"), |
1386 | 1405 | }, |
1387 | 1406 | }, |
| 1407 | + { |
| 1408 | + /* Jumper EZpad 6s Pro */ |
| 1409 | + .driver_data = (void *)&jumper_ezpad_6_pro_b_data, |
| 1410 | + .matches = { |
| 1411 | + DMI_MATCH(DMI_SYS_VENDOR, "Jumper"), |
| 1412 | + DMI_MATCH(DMI_PRODUCT_NAME, "Ezpad"), |
| 1413 | + /* Above matches are too generic, add bios match */ |
| 1414 | + DMI_MATCH(DMI_BIOS_VERSION, "E.WSA116_8.E1.042.bin"), |
| 1415 | + DMI_MATCH(DMI_BIOS_DATE, "01/08/2020"), |
| 1416 | + }, |
| 1417 | + }, |
1388 | 1418 | { |
1389 | 1419 | /* Jumper EZpad 6 m4 */ |
1390 | 1420 | .driver_data = (void *)&jumper_ezpad_6_m4_data, |
@@ -1624,6 +1654,15 @@ const struct dmi_system_id touchscreen_dmi_table[] = { |
1624 | 1654 | DMI_MATCH(DMI_PRODUCT_NAME, "SCT101CTM"), |
1625 | 1655 | }, |
1626 | 1656 | }, |
| 1657 | + { |
| 1658 | + /* GlobalSpace SoLT IVW 11.6" */ |
| 1659 | + .driver_data = (void *)&globalspace_solt_ivw116_data, |
| 1660 | + .matches = { |
| 1661 | + DMI_MATCH(DMI_SYS_VENDOR, "Globalspace Tech Pvt Ltd"), |
| 1662 | + DMI_MATCH(DMI_PRODUCT_NAME, "SolTIVW"), |
| 1663 | + DMI_MATCH(DMI_PRODUCT_SKU, "PN20170413488"), |
| 1664 | + }, |
| 1665 | + }, |
1627 | 1666 | { |
1628 | 1667 | /* Techbite Arc 11.6 */ |
1629 | 1668 | .driver_data = (void *)&techbite_arc_11_6_data, |
@@ -1817,7 +1856,7 @@ const struct dmi_system_id touchscreen_dmi_table[] = { |
1817 | 1856 | { } |
1818 | 1857 | }; |
1819 | 1858 |
|
1820 | | -static const struct ts_dmi_data *ts_data; |
| 1859 | +static struct ts_dmi_data *ts_data; |
1821 | 1860 |
|
1822 | 1861 | static void ts_dmi_add_props(struct i2c_client *client) |
1823 | 1862 | { |
@@ -1852,20 +1891,90 @@ static int ts_dmi_notifier_call(struct notifier_block *nb, |
1852 | 1891 | return 0; |
1853 | 1892 | } |
1854 | 1893 |
|
| 1894 | +#define MAX_CMDLINE_PROPS 16 |
| 1895 | + |
| 1896 | +static struct property_entry ts_cmdline_props[MAX_CMDLINE_PROPS + 1]; |
| 1897 | + |
| 1898 | +static struct ts_dmi_data ts_cmdline_data = { |
| 1899 | + .properties = ts_cmdline_props, |
| 1900 | +}; |
| 1901 | + |
| 1902 | +static int __init ts_parse_props(char *str) |
| 1903 | +{ |
| 1904 | + /* Save the original str to show it on syntax errors */ |
| 1905 | + char orig_str[256]; |
| 1906 | + char *name, *value; |
| 1907 | + u32 u32val; |
| 1908 | + int i, ret; |
| 1909 | + |
| 1910 | + strscpy(orig_str, str, sizeof(orig_str)); |
| 1911 | + |
| 1912 | + /* |
| 1913 | + * str is part of the static_command_line from init/main.c and poking |
| 1914 | + * holes in that by writing 0 to it is allowed, as is taking long |
| 1915 | + * lasting references to it. |
| 1916 | + */ |
| 1917 | + ts_cmdline_data.acpi_name = strsep(&str, ":"); |
| 1918 | + |
| 1919 | + for (i = 0; i < MAX_CMDLINE_PROPS; i++) { |
| 1920 | + name = strsep(&str, ":"); |
| 1921 | + if (!name || !name[0]) |
| 1922 | + break; |
| 1923 | + |
| 1924 | + /* Replace '=' with 0 and make value point past '=' or NULL */ |
| 1925 | + value = name; |
| 1926 | + strsep(&value, "="); |
| 1927 | + if (!value) { |
| 1928 | + ts_cmdline_props[i] = PROPERTY_ENTRY_BOOL(name); |
| 1929 | + } else if (isdigit(value[0])) { |
| 1930 | + ret = kstrtou32(value, 0, &u32val); |
| 1931 | + if (ret) |
| 1932 | + goto syntax_error; |
| 1933 | + |
| 1934 | + ts_cmdline_props[i] = PROPERTY_ENTRY_U32(name, u32val); |
| 1935 | + } else { |
| 1936 | + ts_cmdline_props[i] = PROPERTY_ENTRY_STRING(name, value); |
| 1937 | + } |
| 1938 | + } |
| 1939 | + |
| 1940 | + if (!i || str) |
| 1941 | + goto syntax_error; |
| 1942 | + |
| 1943 | + ts_data = &ts_cmdline_data; |
| 1944 | + return 1; |
| 1945 | + |
| 1946 | +syntax_error: |
| 1947 | + pr_err("Invalid '%s' value for 'i2c_touchscreen_props='\n", orig_str); |
| 1948 | + return 1; /* "i2c_touchscreen_props=" is still a known parameter */ |
| 1949 | +} |
| 1950 | +__setup("i2c_touchscreen_props=", ts_parse_props); |
| 1951 | + |
1855 | 1952 | static struct notifier_block ts_dmi_notifier = { |
1856 | 1953 | .notifier_call = ts_dmi_notifier_call, |
1857 | 1954 | }; |
1858 | 1955 |
|
1859 | 1956 | static int __init ts_dmi_init(void) |
1860 | 1957 | { |
1861 | 1958 | const struct dmi_system_id *dmi_id; |
| 1959 | + struct ts_dmi_data *ts_data_dmi; |
1862 | 1960 | int error; |
1863 | 1961 |
|
1864 | 1962 | dmi_id = dmi_first_match(touchscreen_dmi_table); |
1865 | | - if (!dmi_id) |
| 1963 | + ts_data_dmi = dmi_id ? dmi_id->driver_data : NULL; |
| 1964 | + |
| 1965 | + if (ts_data) { |
| 1966 | + /* |
| 1967 | + * Kernel cmdline provided data takes precedence, copy over |
| 1968 | + * DMI efi_embedded_fw info if available. |
| 1969 | + */ |
| 1970 | + if (ts_data_dmi) |
| 1971 | + ts_data->embedded_fw = ts_data_dmi->embedded_fw; |
| 1972 | + } else if (ts_data_dmi) { |
| 1973 | + ts_data = ts_data_dmi; |
| 1974 | + } else { |
1866 | 1975 | return 0; /* Not an error */ |
| 1976 | + } |
1867 | 1977 |
|
1868 | | - ts_data = dmi_id->driver_data; |
1869 | 1978 | /* Some dmi table entries only provide an efi_embedded_fw_desc */ |
1870 | 1979 | if (!ts_data->properties) |
1871 | 1980 | return 0; |
|
0 commit comments