diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-18 03:45:00 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-18 03:45:00 +0300 |
commit | af79ce47efabba36d1db0902d46a80de7f251411 (patch) | |
tree | 571106db25ed2da54891995aed38407f85e6ac4b /drivers/input/touchscreen | |
parent | c07dee7348e2451bcf2f178bf0e7830268e2c31a (diff) | |
parent | f26e8817b235d8764363bffcc9cbfc61867371f2 (diff) | |
download | linux-af79ce47efabba36d1db0902d46a80de7f251411.tar.xz |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input subsystem updates from Dmitry Torokhov:
- updated support for Synaptics RMI4 devices, including support for
SMBus controllers, firmware update support, sensor tuning, and PS/2
guest support
- ALPS driver now supports tracksticks on SS5 controllers
- i8042 now uses chassis info to skip selftest on Asus laptops as list
of individual models became too unwieldy
- miscellaneous fixes to other drivers
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: (67 commits)
Input: imx6ul_tsc - generalize the averaging property
Input: drv260x - use generic device properties
Input: drv260x - use temporary for &client->dev
Input: drv260x - fix input device's parent assignment
Input: synaptics-rmi4 - add support for F34 V7 bootloader
Input: drv260x - fix initializing overdrive voltage
Input: ALPS - fix protcol -> protocol
Input: i8042 - comment #else/#endif of CONFIG_PNP
Input: lpc32xx-keys - fix invalid error handling of a requested irq
Input: synaptics-rmi4 - fix debug for sensor clip
Input: synaptics-rmi4 - store the attn data in the driver
Input: synaptics-rmi4 - allow to add attention data
Input: synaptics-rmi4 - f03 - grab data passed by transport device
Input: synaptics-rmi4 - add support for F03
Input: imx6ul_tsc - convert int to u32
Input: imx6ul_tsc - add mask when set REG_ADC_CFG
Input: synaptics-rmi4 - have only one struct platform data
Input: synaptics-rmi4 - remove EXPORT_SYMBOL_GPL for internal functions
Input: synaptics-rmi4 - remove mutex calls while updating the firmware
Input: drv2667 - fix misuse of regmap_update_bits
...
Diffstat (limited to 'drivers/input/touchscreen')
-rw-r--r-- | drivers/input/touchscreen/fsl-imx25-tcq.c | 1 | ||||
-rw-r--r-- | drivers/input/touchscreen/imx6ul_tsc.c | 83 | ||||
-rw-r--r-- | drivers/input/touchscreen/melfas_mip4.c | 51 | ||||
-rw-r--r-- | drivers/input/touchscreen/raydium_i2c_ts.c | 2 | ||||
-rw-r--r-- | drivers/input/touchscreen/silead.c | 29 |
5 files changed, 141 insertions, 25 deletions
diff --git a/drivers/input/touchscreen/fsl-imx25-tcq.c b/drivers/input/touchscreen/fsl-imx25-tcq.c index fe9877a6af9e..d50ee490c9cc 100644 --- a/drivers/input/touchscreen/fsl-imx25-tcq.c +++ b/drivers/input/touchscreen/fsl-imx25-tcq.c @@ -55,6 +55,7 @@ static const struct of_device_id mx25_tcq_ids[] = { { .compatible = "fsl,imx25-tcq", }, { /* Sentinel */ } }; +MODULE_DEVICE_TABLE(of, mx25_tcq_ids); #define TSC_4WIRE_PRE_INDEX 0 #define TSC_4WIRE_X_INDEX 1 diff --git a/drivers/input/touchscreen/imx6ul_tsc.c b/drivers/input/touchscreen/imx6ul_tsc.c index 8275267eac25..7098e0a47019 100644 --- a/drivers/input/touchscreen/imx6ul_tsc.c +++ b/drivers/input/touchscreen/imx6ul_tsc.c @@ -21,17 +21,25 @@ #include <linux/platform_device.h> #include <linux/clk.h> #include <linux/io.h> +#include <linux/log2.h> /* ADC configuration registers field define */ #define ADC_AIEN (0x1 << 7) #define ADC_CONV_DISABLE 0x1F +#define ADC_AVGE (0x1 << 5) #define ADC_CAL (0x1 << 7) #define ADC_CALF 0x2 #define ADC_12BIT_MODE (0x2 << 2) +#define ADC_CONV_MODE_MASK (0x3 << 2) #define ADC_IPG_CLK 0x00 +#define ADC_INPUT_CLK_MASK 0x3 #define ADC_CLK_DIV_8 (0x03 << 5) +#define ADC_CLK_DIV_MASK (0x3 << 5) #define ADC_SHORT_SAMPLE_MODE (0x0 << 4) +#define ADC_SAMPLE_MODE_MASK (0x1 << 4) #define ADC_HARDWARE_TRIGGER (0x1 << 13) +#define ADC_AVGS_SHIFT 14 +#define ADC_AVGS_MASK (0x3 << 14) #define SELECT_CHANNEL_4 0x04 #define SELECT_CHANNEL_1 0x01 #define DISABLE_CONVERSION_INT (0x0 << 7) @@ -84,8 +92,10 @@ struct imx6ul_tsc { struct clk *adc_clk; struct gpio_desc *xnur_gpio; - int measure_delay_time; - int pre_charge_time; + u32 measure_delay_time; + u32 pre_charge_time; + bool average_enable; + u32 average_select; struct completion completion; }; @@ -96,17 +106,23 @@ struct imx6ul_tsc { */ static int imx6ul_adc_init(struct imx6ul_tsc *tsc) { - int adc_hc = 0; - int adc_gc; - int adc_gs; - int adc_cfg; - int timeout; + u32 adc_hc = 0; + u32 adc_gc; + u32 adc_gs; + u32 adc_cfg; + unsigned long timeout; reinit_completion(&tsc->completion); adc_cfg = readl(tsc->adc_regs + REG_ADC_CFG); + adc_cfg &= ~(ADC_CONV_MODE_MASK | ADC_INPUT_CLK_MASK); adc_cfg |= ADC_12BIT_MODE | ADC_IPG_CLK; + adc_cfg &= ~(ADC_CLK_DIV_MASK | ADC_SAMPLE_MODE_MASK); adc_cfg |= ADC_CLK_DIV_8 | ADC_SHORT_SAMPLE_MODE; + if (tsc->average_enable) { + adc_cfg &= ~ADC_AVGS_MASK; + adc_cfg |= (tsc->average_select) << ADC_AVGS_SHIFT; + } adc_cfg &= ~ADC_HARDWARE_TRIGGER; writel(adc_cfg, tsc->adc_regs + REG_ADC_CFG); @@ -118,6 +134,8 @@ static int imx6ul_adc_init(struct imx6ul_tsc *tsc) /* start ADC calibration */ adc_gc = readl(tsc->adc_regs + REG_ADC_GC); adc_gc |= ADC_CAL; + if (tsc->average_enable) + adc_gc |= ADC_AVGE; writel(adc_gc, tsc->adc_regs + REG_ADC_GC); timeout = wait_for_completion_timeout @@ -148,7 +166,7 @@ static int imx6ul_adc_init(struct imx6ul_tsc *tsc) */ static void imx6ul_tsc_channel_config(struct imx6ul_tsc *tsc) { - int adc_hc0, adc_hc1, adc_hc2, adc_hc3, adc_hc4; + u32 adc_hc0, adc_hc1, adc_hc2, adc_hc3, adc_hc4; adc_hc0 = DISABLE_CONVERSION_INT; writel(adc_hc0, tsc->adc_regs + REG_ADC_HC0); @@ -173,8 +191,8 @@ static void imx6ul_tsc_channel_config(struct imx6ul_tsc *tsc) */ static void imx6ul_tsc_set(struct imx6ul_tsc *tsc) { - int basic_setting = 0; - int start; + u32 basic_setting = 0; + u32 start; basic_setting |= tsc->measure_delay_time << 8; basic_setting |= DETECT_4_WIRE_MODE | AUTO_MEASURE; @@ -209,8 +227,8 @@ static int imx6ul_tsc_init(struct imx6ul_tsc *tsc) static void imx6ul_tsc_disable(struct imx6ul_tsc *tsc) { - int tsc_flow; - int adc_cfg; + u32 tsc_flow; + u32 adc_cfg; /* TSC controller enters to idle status */ tsc_flow = readl(tsc->tsc_regs + REG_TSC_FLOW_CONTROL); @@ -227,8 +245,8 @@ static void imx6ul_tsc_disable(struct imx6ul_tsc *tsc) static bool tsc_wait_detect_mode(struct imx6ul_tsc *tsc) { unsigned long timeout = jiffies + msecs_to_jiffies(2); - int state_machine; - int debug_mode2; + u32 state_machine; + u32 debug_mode2; do { if (time_after(jiffies, timeout)) @@ -246,10 +264,10 @@ static bool tsc_wait_detect_mode(struct imx6ul_tsc *tsc) static irqreturn_t tsc_irq_fn(int irq, void *dev_id) { struct imx6ul_tsc *tsc = dev_id; - int status; - int value; - int x, y; - int start; + u32 status; + u32 value; + u32 x, y; + u32 start; status = readl(tsc->tsc_regs + REG_TSC_INT_STATUS); @@ -289,8 +307,8 @@ static irqreturn_t tsc_irq_fn(int irq, void *dev_id) static irqreturn_t adc_irq_fn(int irq, void *dev_id) { struct imx6ul_tsc *tsc = dev_id; - int coco; - int value; + u32 coco; + u32 value; coco = readl(tsc->adc_regs + REG_ADC_HS); if (coco & 0x01) { @@ -346,6 +364,7 @@ static int imx6ul_tsc_probe(struct platform_device *pdev) int err; int tsc_irq; int adc_irq; + u32 average_samples; tsc = devm_kzalloc(&pdev->dev, sizeof(*tsc), GFP_KERNEL); if (!tsc) @@ -450,6 +469,30 @@ static int imx6ul_tsc_probe(struct platform_device *pdev) if (err) tsc->pre_charge_time = 0xfff; + err = of_property_read_u32(np, "touchscreen-average-samples", + &average_samples); + if (err) + average_samples = 1; + + switch (average_samples) { + case 1: + tsc->average_enable = false; + tsc->average_select = 0; /* value unused; initialize anyway */ + break; + case 4: + case 8: + case 16: + case 32: + tsc->average_enable = true; + tsc->average_select = ilog2(average_samples) - 2; + break; + default: + dev_err(&pdev->dev, + "touchscreen-average-samples (%u) must be 1, 4, 8, 16 or 32\n", + average_samples); + return -EINVAL; + } + err = input_register_device(tsc->input); if (err) { dev_err(&pdev->dev, diff --git a/drivers/input/touchscreen/melfas_mip4.c b/drivers/input/touchscreen/melfas_mip4.c index 552a3773f79d..703d7f983d0a 100644 --- a/drivers/input/touchscreen/melfas_mip4.c +++ b/drivers/input/touchscreen/melfas_mip4.c @@ -33,7 +33,7 @@ /***************************************************************** * Protocol - * Version : MIP 4.0 Rev 4.6 + * Version : MIP 4.0 Rev 5.4 *****************************************************************/ /* Address */ @@ -81,6 +81,9 @@ #define MIP4_R1_INFO_IC_HW_CATEGORY 0x77 #define MIP4_R1_INFO_CONTACT_THD_SCR 0x78 #define MIP4_R1_INFO_CONTACT_THD_KEY 0x7A +#define MIP4_R1_INFO_PID 0x7C +#define MIP4_R1_INFO_VID 0x7E +#define MIP4_R1_INFO_SLAVE_ADDR 0x80 #define MIP4_R0_EVENT 0x02 #define MIP4_R1_EVENT_SUPPORTED_FUNC 0x00 @@ -157,7 +160,9 @@ struct mip4_ts { char phys[32]; char product_name[16]; + u16 product_id; char ic_name[4]; + char fw_name[32]; unsigned int max_x; unsigned int max_y; @@ -264,6 +269,23 @@ static int mip4_query_device(struct mip4_ts *ts) dev_dbg(&ts->client->dev, "product name: %.*s\n", (int)sizeof(ts->product_name), ts->product_name); + /* Product ID */ + cmd[0] = MIP4_R0_INFO; + cmd[1] = MIP4_R1_INFO_PID; + error = mip4_i2c_xfer(ts, cmd, sizeof(cmd), buf, 2); + if (error) { + dev_warn(&ts->client->dev, + "Failed to retrieve product id: %d\n", error); + } else { + ts->product_id = get_unaligned_le16(&buf[0]); + dev_dbg(&ts->client->dev, "product id: %04X\n", ts->product_id); + } + + /* Firmware name */ + snprintf(ts->fw_name, sizeof(ts->fw_name), + "melfas_mip4_%04X.fw", ts->product_id); + dev_dbg(&ts->client->dev, "firmware name: %s\n", ts->fw_name); + /* IC name */ cmd[0] = MIP4_R0_INFO; cmd[1] = MIP4_R1_INFO_IC_NAME; @@ -1269,11 +1291,11 @@ static ssize_t mip4_sysfs_fw_update(struct device *dev, const struct firmware *fw; int error; - error = request_firmware(&fw, MIP4_FW_NAME, dev); + error = request_firmware(&fw, ts->fw_name, dev); if (error) { dev_err(&ts->client->dev, "Failed to retrieve firmware %s: %d\n", - MIP4_FW_NAME, error); + ts->fw_name, error); return error; } @@ -1348,6 +1370,25 @@ static ssize_t mip4_sysfs_read_hw_version(struct device *dev, static DEVICE_ATTR(hw_version, S_IRUGO, mip4_sysfs_read_hw_version, NULL); +static ssize_t mip4_sysfs_read_product_id(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct mip4_ts *ts = i2c_get_clientdata(client); + size_t count; + + mutex_lock(&ts->input->mutex); + + count = snprintf(buf, PAGE_SIZE, "%04X\n", ts->product_id); + + mutex_unlock(&ts->input->mutex); + + return count; +} + +static DEVICE_ATTR(product_id, S_IRUGO, mip4_sysfs_read_product_id, NULL); + static ssize_t mip4_sysfs_read_ic_name(struct device *dev, struct device_attribute *attr, char *buf) @@ -1371,6 +1412,7 @@ static DEVICE_ATTR(ic_name, S_IRUGO, mip4_sysfs_read_ic_name, NULL); static struct attribute *mip4_attrs[] = { &dev_attr_fw_version.attr, &dev_attr_hw_version.attr, + &dev_attr_product_id.attr, &dev_attr_ic_name.attr, &dev_attr_update_fw.attr, NULL, @@ -1435,6 +1477,7 @@ static int mip4_probe(struct i2c_client *client, const struct i2c_device_id *id) input->id.bustype = BUS_I2C; input->id.vendor = 0x13c5; + input->id.product = ts->product_id; input->open = mip4_input_open; input->close = mip4_input_close; @@ -1572,6 +1615,6 @@ static struct i2c_driver mip4_driver = { module_i2c_driver(mip4_driver); MODULE_DESCRIPTION("MELFAS MIP4 Touchscreen"); -MODULE_VERSION("2016.09.28"); +MODULE_VERSION("2016.10.31"); MODULE_AUTHOR("Sangwon Jee <jeesw@melfas.com>"); MODULE_LICENSE("GPL"); diff --git a/drivers/input/touchscreen/raydium_i2c_ts.c b/drivers/input/touchscreen/raydium_i2c_ts.c index a99fb5cac5a0..2658afa016c9 100644 --- a/drivers/input/touchscreen/raydium_i2c_ts.c +++ b/drivers/input/touchscreen/raydium_i2c_ts.c @@ -669,7 +669,7 @@ static int raydium_i2c_do_update_firmware(struct raydium_data *ts, if (ts->boot_mode == RAYDIUM_TS_MAIN) { dev_err(&client->dev, - "failied to jump to boot loader: %d\n", + "failed to jump to boot loader: %d\n", error); return -EIO; } diff --git a/drivers/input/touchscreen/silead.c b/drivers/input/touchscreen/silead.c index f502c8488be8..404830a4a366 100644 --- a/drivers/input/touchscreen/silead.c +++ b/drivers/input/touchscreen/silead.c @@ -29,6 +29,7 @@ #include <linux/input/touchscreen.h> #include <linux/pm.h> #include <linux/irq.h> +#include <linux/regulator/consumer.h> #include <asm/unaligned.h> @@ -73,6 +74,7 @@ struct silead_ts_data { struct i2c_client *client; struct gpio_desc *gpio_power; struct input_dev *input; + struct regulator_bulk_data regulators[2]; char fw_name[64]; struct touchscreen_properties prop; u32 max_fingers; @@ -433,6 +435,13 @@ static int silead_ts_set_default_fw_name(struct silead_ts_data *data, } #endif +static void silead_disable_regulator(void *arg) +{ + struct silead_ts_data *data = arg; + + regulator_bulk_disable(ARRAY_SIZE(data->regulators), data->regulators); +} + static int silead_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -465,6 +474,26 @@ static int silead_ts_probe(struct i2c_client *client, if (client->irq <= 0) return -ENODEV; + data->regulators[0].supply = "vddio"; + data->regulators[1].supply = "avdd"; + error = devm_regulator_bulk_get(dev, ARRAY_SIZE(data->regulators), + data->regulators); + if (error) + return error; + + /* + * Enable regulators at probe and disable them at remove, we need + * to keep the chip powered otherwise it forgets its firmware. + */ + error = regulator_bulk_enable(ARRAY_SIZE(data->regulators), + data->regulators); + if (error) + return error; + + error = devm_add_action_or_reset(dev, silead_disable_regulator, data); + if (error) + return error; + /* Power GPIO pin */ data->gpio_power = devm_gpiod_get_optional(dev, "power", GPIOD_OUT_LOW); if (IS_ERR(data->gpio_power)) { |