diff options
| -rw-r--r-- | Documentation/devicetree/bindings/input/touchscreen/gt9xx/gt9xx.txt | 79 | ||||
| -rw-r--r-- | Documentation/devicetree/bindings/vendor-prefixes.txt | 1 | ||||
| -rw-r--r-- | arch/arm/boot/dts/qcom/msmcobalt-coresight.dtsi | 10 | ||||
| -rw-r--r-- | drivers/clk/msm/clock-gcc-cobalt.c | 16 | ||||
| -rw-r--r-- | drivers/hwtracing/coresight/coresight-tpda.c | 6 | ||||
| -rw-r--r-- | drivers/input/touchscreen/Kconfig | 12 | ||||
| -rw-r--r-- | drivers/input/touchscreen/gt9xx/gt9xx.c | 547 | ||||
| -rw-r--r-- | drivers/input/touchscreen/gt9xx/gt9xx.h | 25 | ||||
| -rw-r--r-- | drivers/misc/qcom/qdsp6v2/audio_utils.c | 15 | ||||
| -rw-r--r-- | drivers/usb/core/devio.c | 9 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss.h | 1 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp.c | 1 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_hwio.h | 1 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c | 8 | ||||
| -rw-r--r-- | include/dt-bindings/clock/msm-clocks-cobalt.h | 1 | ||||
| -rw-r--r-- | include/sound/q6asm-v2.h | 2 | ||||
| -rw-r--r-- | sound/soc/msm/qdsp6v2/q6asm.c | 4 |
17 files changed, 668 insertions, 70 deletions
diff --git a/Documentation/devicetree/bindings/input/touchscreen/gt9xx/gt9xx.txt b/Documentation/devicetree/bindings/input/touchscreen/gt9xx/gt9xx.txt new file mode 100644 index 000000000000..af09840bb053 --- /dev/null +++ b/Documentation/devicetree/bindings/input/touchscreen/gt9xx/gt9xx.txt @@ -0,0 +1,79 @@ +Goodix GT9xx series touch controller + +The Goodix GT9xx series touch controller is connected to the host processor via +I2C. The controller generates interrupts when the user touches the panel. The +host controller is expected to read the touch coordinates over I2C and pass +the coordinates to the rest of the system. + +Required properties: + + - compatible : Should be "goodix,gt9xx" + - reg : I2C slave address of the device. + - interrupt-parent : Parent of interrupt. + - interrupts : Configuration of touch panel controller interrupt + GPIO. + - goodix,family-id : Family identification of the controller. + - interrupt-gpios : Interrupt gpio which is to provide interrupts to + host, same as "interrupts" node. + - reset-gpios : Reset gpio to control the reset of chip. + - goodix,display-coords : Display coordinates in pixels. It is a four + tuple consisting of min x, min y, max x and + max y values. + +Optional properties: + + - avdd-supply : Power supply needed to power up the device, this is + for fixed voltage external regulator. + - vdd-supply : Power supply needed to power up the device, when use + external regulator, do not add this property. + - vcc-i2c-supply : Power source required to power up i2c bus. + GT9xx series can provide 1.8V from internal + LDO, add this properties base on hardware + design. + - goodix,panel-coords : Panel coordinates for the chip in pixels. + It is a four tuple consisting of min x, + min y, max x and max y values. + - goodix,i2c-pull-up : To specify pull up is required. + - goodix,no-force-update : To specify force update is allowed. + - goodix,button-map : Button map of key codes. The number of key codes + depend on panel. + - goodix,cfg-data : Touchpanel controller configuration data, ask vendor + to provide that. Default configuration will be + used if this property is not present. + +Example: +i2c@f9927000 { + goodix@5d { + compatible = "goodix,gt9xx"; + reg = <0x5d>; + interrupt-parent = <&msmgpio>; + interrupts = <17 0x2008>; + reset-gpios = <&msmgpio 16 0x00>; + interrupt-gpios = <&msmgpio 17 0x00>; + avdd-supply = <&tp_power>; + goodix,panel-coords = <0 0 720 1200>; + goodix,display-coords = <0 0 720 1080>; + goodix,button-map= <158 102 139>; + goodix,family-id = <0x0>; + goodix,cfg-data = [ + 41 D0 02 00 05 0A 05 01 01 08 + 12 58 50 41 03 05 00 00 00 00 + 00 00 00 00 00 00 00 8C 2E 0E + 28 24 73 13 00 00 00 83 03 1D + 40 02 00 00 00 03 64 32 00 00 + 00 1A 38 94 C0 02 00 00 00 04 + 9E 1C 00 8D 20 00 7A 26 00 6D + 2C 00 60 34 00 60 10 38 68 00 + F0 50 35 FF FF 27 00 00 00 00 + 00 01 1B 14 0C 14 00 00 01 00 + 00 00 00 00 00 00 00 00 00 00 + 00 00 02 04 06 08 0A 0C 0E 10 + 12 14 16 18 1A 1C FF FF FF FF + FF FF FF FF FF FF FF FF FF FF + FF FF 00 02 04 06 08 0A 0C 0F + 10 12 13 14 16 18 1C 1D 1E 1F + 20 21 22 24 26 28 29 2A FF FF + FF FF FF FF FF FF FF 22 22 22 + 22 22 22 FF 07 01]; + }; +}; diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index aca2dd3e4ccb..1d7e54f68ee4 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt @@ -87,6 +87,7 @@ firefly Firefly focaltech FocalTech Systems Co.,Ltd fsl Freescale Semiconductor GEFanuc GE Fanuc Intelligent Platforms Embedded Systems, Inc. +goodix Goodix. Ltd. gef GE Fanuc Intelligent Platforms Embedded Systems, Inc. geniatech Geniatech, Inc. giantplus Giantplus Technology Co., Ltd. diff --git a/arch/arm/boot/dts/qcom/msmcobalt-coresight.dtsi b/arch/arm/boot/dts/qcom/msmcobalt-coresight.dtsi index 4afaa3aa51be..aeb6bf6141d8 100644 --- a/arch/arm/boot/dts/qcom/msmcobalt-coresight.dtsi +++ b/arch/arm/boot/dts/qcom/msmcobalt-coresight.dtsi @@ -39,10 +39,18 @@ }; replicator: replicator@6046000 { - compatible = "arm,coresight-replicator"; + compatible = "arm,primecell"; + arm,primecell-periphid = <0x0003b909>; + + reg = <0x6046000 0x1000>; + reg-names = "replicator-base"; coresight-name = "coresight-replicator"; + clocks = <&clock_gcc clk_qdss_clk>, + <&clock_gcc clk_qdss_a_clk>; + clock-names = "apb_pclk", "core_a_clk"; + ports{ #address-cells = <1>; #size-cells = <0>; diff --git a/drivers/clk/msm/clock-gcc-cobalt.c b/drivers/clk/msm/clock-gcc-cobalt.c index 71c5541d0c0d..05272118af16 100644 --- a/drivers/clk/msm/clock-gcc-cobalt.c +++ b/drivers/clk/msm/clock-gcc-cobalt.c @@ -241,8 +241,8 @@ DEFINE_EXT_CLK(gpll4_out_main, &gpll4.c); static struct clk_freq_tbl ftbl_hmss_ahb_clk_src[] = { F( 19200000, cxo_clk_src_ao, 1, 0, 0), - F( 37500000, gpll0_out_main, 16, 0, 0), - F( 75000000, gpll0_out_main, 8, 0, 0), + F( 50000000, gpll0_out_main, 12, 0, 0), + F( 100000000, gpll0_out_main, 6, 0, 0), F_END }; @@ -1200,6 +1200,17 @@ static struct branch_clk gcc_aggre1_ufs_axi_clk = { }, }; +static struct hw_ctl_clk gcc_aggre1_ufs_axi_hw_ctl_clk = { + .cbcr_reg = GCC_AGGRE1_UFS_AXI_CBCR, + .base = &virt_base, + .c = { + .dbg_name = "gcc_aggre1_ufs_axi_hw_ctl_clk", + .parent = &gcc_aggre1_ufs_axi_clk.c, + .ops = &clk_ops_branch_hw_ctl, + CLK_INIT(gcc_aggre1_ufs_axi_hw_ctl_clk.c), + }, +}; + static struct branch_clk gcc_aggre1_usb3_axi_clk = { .cbcr_reg = GCC_AGGRE1_USB3_AXI_CBCR, .has_sibling = 1, @@ -2597,6 +2608,7 @@ static struct clk_lookup msm_clocks_gcc_cobalt[] = { CLK_LIST(gcc_qusb2phy_sec_reset), CLK_LIST(gpll0_out_msscc), CLK_LIST(gcc_aggre1_ufs_axi_clk), + CLK_LIST(gcc_aggre1_ufs_axi_hw_ctl_clk), CLK_LIST(gcc_aggre1_usb3_axi_clk), CLK_LIST(gcc_bimc_mss_q6_axi_clk), CLK_LIST(gcc_blsp1_ahb_clk), diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c index e4e188fc67fc..c43d8596a203 100644 --- a/drivers/hwtracing/coresight/coresight-tpda.c +++ b/drivers/hwtracing/coresight/coresight-tpda.c @@ -94,6 +94,10 @@ static void __tpda_enable_pre_port(struct tpda_drvdata *drvdata) val = val | BIT(2); else val = val & ~BIT(2); + + /* Force ASYNC-VERSION-FREQTS sequence */ + val = val | BIT(21); + tpda_writel(drvdata, val, TPDA_CR); /* @@ -154,8 +158,6 @@ static void __tpda_enable_post_port(struct tpda_drvdata *drvdata) if (drvdata->freq_req_val) tpda_writel(drvdata, drvdata->freq_req_val, TPDA_FREQREQ_VAL); - else - tpda_writel(drvdata, 0x0, TPDA_FREQREQ_VAL); val = tpda_readl(drvdata, TPDA_CR); if (drvdata->freq_req) diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index b02abfc58aea..b9956170b909 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -1205,4 +1205,16 @@ config FT_SECURE_TOUCH If unsure, say N. +config TOUCHSCREEN_IT7260_I2C + tristate "IT7260 Touchscreen Driver" + depends on I2C + help + Say Y here if you have a IT7260 Touchscreen Driver + connected to your system. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called it7258_ts_i2c. + endif diff --git a/drivers/input/touchscreen/gt9xx/gt9xx.c b/drivers/input/touchscreen/gt9xx/gt9xx.c index 6615c3a039a0..ebb9ce7ba6a4 100644 --- a/drivers/input/touchscreen/gt9xx/gt9xx.c +++ b/drivers/input/touchscreen/gt9xx/gt9xx.c @@ -40,8 +40,11 @@ * By Meta, 2013/06/08 */ +#include <linux/regulator/consumer.h> #include "gt9xx.h" +#include <linux/of_gpio.h> + #if GTP_ICS_SLOT_REPORT #include <linux/input/mt.h> #endif @@ -55,6 +58,15 @@ #define GTP_I2C_ADDRESS_HIGH 0x14 #define GTP_I2C_ADDRESS_LOW 0x5D +#define GOODIX_VTG_MIN_UV 2600000 +#define GOODIX_VTG_MAX_UV 3300000 +#define GOODIX_I2C_VTG_MIN_UV 1800000 +#define GOODIX_I2C_VTG_MAX_UV 1800000 +#define GOODIX_VDD_LOAD_MIN_UA 0 +#define GOODIX_VDD_LOAD_MAX_UA 10000 +#define GOODIX_VIO_LOAD_MIN_UA 0 +#define GOODIX_VIO_LOAD_MAX_UA 10000 + #define RESET_DELAY_T3_US 200 /* T3: > 100us */ #define RESET_DELAY_T4 20 /* T4: > 5ms */ @@ -80,7 +92,10 @@ static void gtp_reset_guitar(struct goodix_ts_data *ts, int ms); static void gtp_int_sync(struct goodix_ts_data *ts, int ms); static int gtp_i2c_test(struct i2c_client *client); -#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_FB) +static int fb_notifier_callback(struct notifier_block *self, + unsigned long event, void *data); +#elif defined(CONFIG_HAS_EARLYSUSPEND) static void goodix_ts_early_suspend(struct early_suspend *h); static void goodix_ts_late_resume(struct early_suspend *h); #endif @@ -755,7 +770,7 @@ static void gtp_reset_guitar(struct goodix_ts_data *ts, int ms) #endif } -#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_FB) #if GTP_SLIDE_WAKEUP /******************************************************* Function: @@ -860,16 +875,12 @@ static s8 gtp_wakeup_sleep(struct goodix_ts_data *ts) GTP_DEBUG_FUNC(); #if GTP_POWER_CTRL_SLEEP - while (retry++ < 5) { - gtp_reset_guitar(ts, 20); + gtp_reset_guitar(ts, 20); - ret = gtp_send_cfg(ts); - if (ret > 0) { - dev_dbg(&ts->client->dev, - "Wakeup sleep send config success."); - continue; - } - dev_dbg(&ts->client->dev, "GTP Wakeup!"); + ret = gtp_send_cfg(ts); + if (ret > 0) { + dev_dbg(&ts->client->dev, + "Wakeup sleep send config success."); return 1; } #else @@ -910,7 +921,7 @@ static s8 gtp_wakeup_sleep(struct goodix_ts_data *ts) dev_err(&ts->client->dev, "GTP wakeup sleep failed.\n"); return ret; } -#endif /* !CONFIG_HAS_EARLYSUSPEND */ +#endif /* !CONFIG_HAS_EARLYSUSPEND && !CONFIG_FB*/ /******************************************************* Function: @@ -1014,21 +1025,27 @@ static int gtp_init_panel(struct goodix_ts_data *ts) return -EINVAL; } - config_data = devm_kzalloc(&client->dev, + if (ts->pdata->gtp_cfg_len) { + config_data = ts->pdata->config_data; + ts->config_data = ts->pdata->config_data; + ts->gtp_cfg_len = ts->pdata->gtp_cfg_len; + } else { + config_data = devm_kzalloc(&client->dev, GTP_CONFIG_MAX_LENGTH + GTP_ADDR_LENGTH, - GFP_KERNEL); - if (!config_data) { - dev_err(&client->dev, - "Not enough memory for panel config data\n"); - return -ENOMEM; - } + GFP_KERNEL); + if (!config_data) { + dev_err(&client->dev, + "Not enough memory for panel config data\n"); + return -ENOMEM; + } - ts->config_data = config_data; - config_data[0] = GTP_REG_CONFIG_DATA >> 8; - config_data[1] = GTP_REG_CONFIG_DATA & 0xff; - memset(&config_data[GTP_ADDR_LENGTH], 0, GTP_CONFIG_MAX_LENGTH); - memcpy(&config_data[GTP_ADDR_LENGTH], send_cfg_buf[sensor_id], - ts->gtp_cfg_len); + ts->config_data = config_data; + config_data[0] = GTP_REG_CONFIG_DATA >> 8; + config_data[1] = GTP_REG_CONFIG_DATA & 0xff; + memset(&config_data[GTP_ADDR_LENGTH], 0, GTP_CONFIG_MAX_LENGTH); + memcpy(&config_data[GTP_ADDR_LENGTH], send_cfg_buf[sensor_id], + ts->gtp_cfg_len); + } #if GTP_CUSTOM_CFG config_data[RESOLUTION_LOC] = @@ -1345,6 +1362,318 @@ exit_free_inputdev: return ret; } +static int reg_set_optimum_mode_check(struct regulator *reg, int load_uA) +{ + return (regulator_count_voltages(reg) > 0) ? + regulator_set_optimum_mode(reg, load_uA) : 0; +} + +/** + * goodix_power_on - Turn device power ON + * @ts: driver private data + * + * Returns zero on success, else an error. + */ +static int goodix_power_on(struct goodix_ts_data *ts) +{ + int ret; + + if (!IS_ERR(ts->avdd)) { + ret = reg_set_optimum_mode_check(ts->avdd, + GOODIX_VDD_LOAD_MAX_UA); + if (ret < 0) { + dev_err(&ts->client->dev, + "Regulator avdd set_opt failed rc=%d\n", ret); + goto err_set_opt_avdd; + } + ret = regulator_enable(ts->avdd); + if (ret) { + dev_err(&ts->client->dev, + "Regulator avdd enable failed ret=%d\n", ret); + goto err_enable_avdd; + } + } + + if (!IS_ERR(ts->vdd)) { + ret = regulator_set_voltage(ts->vdd, GOODIX_VTG_MIN_UV, + GOODIX_VTG_MAX_UV); + if (ret) { + dev_err(&ts->client->dev, + "Regulator set_vtg failed vdd ret=%d\n", ret); + goto err_set_vtg_vdd; + } + ret = reg_set_optimum_mode_check(ts->vdd, + GOODIX_VDD_LOAD_MAX_UA); + if (ret < 0) { + dev_err(&ts->client->dev, + "Regulator vdd set_opt failed rc=%d\n", ret); + goto err_set_opt_vdd; + } + ret = regulator_enable(ts->vdd); + if (ret) { + dev_err(&ts->client->dev, + "Regulator vdd enable failed ret=%d\n", ret); + goto err_enable_vdd; + } + } + + if (!IS_ERR(ts->vcc_i2c)) { + ret = regulator_set_voltage(ts->vcc_i2c, GOODIX_I2C_VTG_MIN_UV, + GOODIX_I2C_VTG_MAX_UV); + if (ret) { + dev_err(&ts->client->dev, + "Regulator set_vtg failed vcc_i2c ret=%d\n", + ret); + goto err_set_vtg_vcc_i2c; + } + ret = reg_set_optimum_mode_check(ts->vcc_i2c, + GOODIX_VIO_LOAD_MAX_UA); + if (ret < 0) { + dev_err(&ts->client->dev, + "Regulator vcc_i2c set_opt failed rc=%d\n", + ret); + goto err_set_opt_vcc_i2c; + } + ret = regulator_enable(ts->vcc_i2c); + if (ret) { + dev_err(&ts->client->dev, + "Regulator vcc_i2c enable failed ret=%d\n", + ret); + regulator_disable(ts->vdd); + goto err_enable_vcc_i2c; + } + } + + return 0; + +err_enable_vcc_i2c: +err_set_opt_vcc_i2c: + if (!IS_ERR(ts->vcc_i2c)) + regulator_set_voltage(ts->vcc_i2c, 0, GOODIX_I2C_VTG_MAX_UV); +err_set_vtg_vcc_i2c: + if (!IS_ERR(ts->vdd)) + regulator_disable(ts->vdd); +err_enable_vdd: +err_set_opt_vdd: + if (!IS_ERR(ts->vdd)) + regulator_set_voltage(ts->vdd, 0, GOODIX_VTG_MAX_UV); +err_set_vtg_vdd: + if (!IS_ERR(ts->avdd)) + regulator_disable(ts->avdd); +err_enable_avdd: +err_set_opt_avdd: + return ret; +} + +/** + * goodix_power_off - Turn device power OFF + * @ts: driver private data + * + * Returns zero on success, else an error. + */ +static int goodix_power_off(struct goodix_ts_data *ts) +{ + int ret; + + if (!IS_ERR(ts->vcc_i2c)) { + ret = regulator_set_voltage(ts->vcc_i2c, 0, + GOODIX_I2C_VTG_MAX_UV); + if (ret < 0) + dev_err(&ts->client->dev, + "Regulator vcc_i2c set_vtg failed ret=%d\n", + ret); + ret = regulator_disable(ts->vcc_i2c); + if (ret) + dev_err(&ts->client->dev, + "Regulator vcc_i2c disable failed ret=%d\n", + ret); + } + + if (!IS_ERR(ts->vdd)) { + ret = regulator_set_voltage(ts->vdd, 0, GOODIX_VTG_MAX_UV); + if (ret < 0) + dev_err(&ts->client->dev, + "Regulator vdd set_vtg failed ret=%d\n", ret); + ret = regulator_disable(ts->vdd); + if (ret) + dev_err(&ts->client->dev, + "Regulator vdd disable failed ret=%d\n", ret); + } + + if (!IS_ERR(ts->avdd)) { + ret = regulator_disable(ts->avdd); + if (ret) + dev_err(&ts->client->dev, + "Regulator avdd disable failed ret=%d\n", ret); + } + + return 0; +} + +/** + * goodix_power_init - Initialize device power + * @ts: driver private data + * + * Returns zero on success, else an error. + */ +static int goodix_power_init(struct goodix_ts_data *ts) +{ + int ret; + + ts->avdd = regulator_get(&ts->client->dev, "avdd"); + if (IS_ERR(ts->avdd)) { + ret = PTR_ERR(ts->avdd); + dev_info(&ts->client->dev, + "Regulator get failed avdd ret=%d\n", ret); + } + + ts->vdd = regulator_get(&ts->client->dev, "vdd"); + if (IS_ERR(ts->vdd)) { + ret = PTR_ERR(ts->vdd); + dev_info(&ts->client->dev, + "Regulator get failed vdd ret=%d\n", ret); + } + + ts->vcc_i2c = regulator_get(&ts->client->dev, "vcc-i2c"); + if (IS_ERR(ts->vcc_i2c)) { + ret = PTR_ERR(ts->vcc_i2c); + dev_info(&ts->client->dev, + "Regulator get failed vcc_i2c ret=%d\n", ret); + } + + return 0; +} + +/** + * goodix_power_deinit - Deinitialize device power + * @ts: driver private data + * + * Returns zero on success, else an error. + */ +static int goodix_power_deinit(struct goodix_ts_data *ts) +{ + regulator_put(ts->vdd); + regulator_put(ts->vcc_i2c); + regulator_put(ts->avdd); + + return 0; +} + +static int goodix_ts_get_dt_coords(struct device *dev, char *name, + struct goodix_ts_platform_data *pdata) +{ + struct property *prop; + struct device_node *np = dev->of_node; + int rc; + u32 coords[GOODIX_COORDS_ARR_SIZE]; + + prop = of_find_property(np, name, NULL); + if (!prop) + return -EINVAL; + if (!prop->value) + return -ENODATA; + + rc = of_property_read_u32_array(np, name, coords, + GOODIX_COORDS_ARR_SIZE); + if (rc && (rc != -EINVAL)) { + dev_err(dev, "Unable to read %s\n", name); + return rc; + } + + if (!strcmp(name, "goodix,panel-coords")) { + pdata->panel_minx = coords[0]; + pdata->panel_miny = coords[1]; + pdata->panel_maxx = coords[2]; + pdata->panel_maxy = coords[3]; + } else if (!strcmp(name, "goodix,display-coords")) { + pdata->x_min = coords[0]; + pdata->y_min = coords[1]; + pdata->x_max = coords[2]; + pdata->y_max = coords[3]; + } else { + dev_err(dev, "unsupported property %s\n", name); + return -EINVAL; + } + + return 0; +} + +static int goodix_parse_dt(struct device *dev, + struct goodix_ts_platform_data *pdata) +{ + int rc; + struct device_node *np = dev->of_node; + struct property *prop; + u32 temp_val, num_buttons; + u32 button_map[MAX_BUTTONS]; + + rc = goodix_ts_get_dt_coords(dev, "goodix,panel-coords", pdata); + if (rc && (rc != -EINVAL)) + return rc; + + rc = goodix_ts_get_dt_coords(dev, "goodix,display-coords", pdata); + if (rc) + return rc; + + pdata->i2c_pull_up = of_property_read_bool(np, + "goodix,i2c-pull-up"); + + pdata->no_force_update = of_property_read_bool(np, + "goodix,no-force-update"); + /* reset, irq gpio info */ + pdata->reset_gpio = of_get_named_gpio_flags(np, "reset-gpios", + 0, &pdata->reset_gpio_flags); + if (pdata->reset_gpio < 0) + return pdata->reset_gpio; + + pdata->irq_gpio = of_get_named_gpio_flags(np, "interrupt-gpios", + 0, &pdata->irq_gpio_flags); + if (pdata->irq_gpio < 0) + return pdata->irq_gpio; + + rc = of_property_read_u32(np, "goodix,family-id", &temp_val); + if (!rc) + pdata->family_id = temp_val; + else + return rc; + + prop = of_find_property(np, "goodix,button-map", NULL); + if (prop) { + num_buttons = prop->length / sizeof(temp_val); + if (num_buttons > MAX_BUTTONS) + return -EINVAL; + + rc = of_property_read_u32_array(np, + "goodix,button-map", button_map, + num_buttons); + if (rc) { + dev_err(dev, "Unable to read key codes\n"); + return rc; + } + } + + prop = of_find_property(np, "goodix,cfg-data", &pdata->gtp_cfg_len); + if (prop && prop->value) { + pdata->config_data = devm_kzalloc(dev, + GTP_CONFIG_MAX_LENGTH + GTP_ADDR_LENGTH, GFP_KERNEL); + if (!pdata->config_data) + return -ENOMEM; + + pdata->config_data[0] = GTP_REG_CONFIG_DATA >> 8; + pdata->config_data[1] = GTP_REG_CONFIG_DATA & 0xff; + memset(&pdata->config_data[GTP_ADDR_LENGTH], 0, + GTP_CONFIG_MAX_LENGTH); + memcpy(&pdata->config_data[GTP_ADDR_LENGTH], + prop->value, pdata->gtp_cfg_len); + } else { + dev_err(dev, + "Unable to get configure data, default will be used.\n"); + pdata->gtp_cfg_len = 0; + } + + return 0; +} + /******************************************************* Function: I2c probe. @@ -1359,15 +1688,34 @@ Output: static int goodix_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) { + struct goodix_ts_platform_data *pdata; struct goodix_ts_data *ts; u16 version_info; int ret; dev_dbg(&client->dev, "GTP I2C Address: 0x%02x\n", client->addr); + if (client->dev.of_node) { + pdata = devm_kzalloc(&client->dev, + sizeof(struct goodix_ts_platform_data), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + ret = goodix_parse_dt(&client->dev, pdata); + if (ret) + return ret; + } else { + pdata = client->dev.platform_data; + } + + if (!pdata) { + dev_err(&client->dev, "GTP invalid pdata\n"); + return -EINVAL; + } #if GTP_ESD_PROTECT i2c_connect_client = client; #endif + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { dev_err(&client->dev, "GTP I2C not supported\n"); return -ENODEV; @@ -1379,14 +1727,26 @@ static int goodix_ts_probe(struct i2c_client *client, memset(ts, 0, sizeof(*ts)); ts->client = client; - /* For kernel 2.6.39 later we spin_lock_init(&ts->irq_lock) + ts->pdata = pdata; + /* For 2.6.39 & later use spin_lock_init(&ts->irq_lock) * For 2.6.39 & before, use ts->irq_lock = SPIN_LOCK_UNLOCKED */ spin_lock_init(&ts->irq_lock); i2c_set_clientdata(client, ts); - ts->gtp_rawdiff_mode = 0; + ret = goodix_power_init(ts); + if (ret) { + dev_err(&client->dev, "GTP power init failed\n"); + goto exit_free_client_data; + } + + ret = goodix_power_on(ts); + if (ret) { + dev_err(&client->dev, "GTP power on failed\n"); + goto exit_deinit_power; + } + ret = gtp_request_io_port(ts); if (ret) { dev_err(&client->dev, "GTP request IO port failed.\n"); @@ -1424,6 +1784,20 @@ static int goodix_ts_probe(struct i2c_client *client, goto exit_free_inputdev; } +#if defined(CONFIG_FB) + ts->fb_notif.notifier_call = fb_notifier_callback; + ret = fb_register_client(&ts->fb_notif); + if (ret) + dev_err(&ts->client->dev, + "Unable to register fb_notifier: %d\n", + ret); +#elif defined(CONFIG_HAS_EARLYSUSPEND) + ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; + ts->early_suspend.suspend = goodix_ts_early_suspend; + ts->early_suspend.resume = goodix_ts_late_resume; + register_early_suspend(&ts->early_suspend); +#endif + ts->goodix_wq = create_singlethread_workqueue("goodix_wq"); INIT_WORK(&ts->work, goodix_ts_work_func); @@ -1451,6 +1825,13 @@ static int goodix_ts_probe(struct i2c_client *client, init_done = true; return 0; exit_free_irq: +#if defined(CONFIG_FB) + if (fb_unregister_client(&ts->fb_notif)) + dev_err(&client->dev, + "Error occurred while unregistering fb_notifier.\n"); +#elif defined(CONFIG_HAS_EARLYSUSPEND) + unregister_early_suspend(&ts->early_suspend); +#endif if (ts->use_irq) free_irq(client->irq, ts); else @@ -1467,7 +1848,15 @@ exit_free_irq: exit_free_inputdev: kfree(ts->config_data); exit_free_io_port: + if (gpio_is_valid(pdata->reset_gpio)) + gpio_free(pdata->reset_gpio); + if (gpio_is_valid(pdata->irq_gpio)) + gpio_free(pdata->irq_gpio); exit_power_off: + goodix_power_off(ts); +exit_deinit_power: + goodix_power_deinit(ts); +exit_free_client_data: i2c_set_clientdata(client, NULL); kfree(ts); return ret; @@ -1486,7 +1875,11 @@ static int goodix_ts_remove(struct i2c_client *client) struct goodix_ts_data *ts = i2c_get_clientdata(client); GTP_DEBUG_FUNC(); -#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_FB) + if (fb_unregister_client(&ts->fb_notif)) + dev_err(&client->dev, + "Error occurred while unregistering fb_notifier.\n"); +#elif defined(CONFIG_HAS_EARLYSUSPEND) unregister_early_suspend(&ts->early_suspend); #endif @@ -1522,6 +1915,8 @@ static int goodix_ts_remove(struct i2c_client *client) if (gpio_is_valid(ts->pdata->irq_gpio)) gpio_free(ts->pdata->irq_gpio); + goodix_power_off(ts); + goodix_power_deinit(ts); i2c_set_clientdata(client, NULL); kfree(ts); } @@ -1529,7 +1924,7 @@ static int goodix_ts_remove(struct i2c_client *client) return 0; } -#ifdef CONFIG_HAS_EARLYSUSPEND +#if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_FB) /******************************************************* Function: Early suspend function. @@ -1538,12 +1933,9 @@ Input: Output: None. *******************************************************/ -static void goodix_ts_early_suspend(struct early_suspend *h) +static void goodix_ts_suspend(struct goodix_ts_data *ts) { - struct goodix_ts_data *ts; - s8 ret = -1; - - ts = container_of(h, struct goodix_ts_data, early_suspend); + int ret = -1; GTP_DEBUG_FUNC(); @@ -1577,12 +1969,9 @@ Input: Output: None. *******************************************************/ -static void goodix_ts_late_resume(struct early_suspend *h) +static void goodix_ts_resume(struct goodix_ts_data *ts) { - struct goodix_ts_data *ts; - s8 ret = -1; - - ts = container_of(h, struct goodix_ts_data, early_suspend); + int ret = -1; GTP_DEBUG_FUNC(); @@ -1593,7 +1982,7 @@ static void goodix_ts_late_resume(struct early_suspend *h) #endif if (ret < 0) - dev_err(&ts->client->dev, "GTP later resume failed.\n"); + dev_err(&ts->client->dev, "GTP resume failed.\n"); if (ts->use_irq) gtp_irq_enable(ts); @@ -1606,18 +1995,72 @@ static void goodix_ts_late_resume(struct early_suspend *h) gtp_esd_switch(ts->client, SWITCH_ON); #endif } + +#if defined(CONFIG_FB) +static int fb_notifier_callback(struct notifier_block *self, + unsigned long event, void *data) +{ + struct fb_event *evdata = data; + int *blank; + struct goodix_ts_data *ts = + container_of(self, struct goodix_ts_data, fb_notif); + + if (evdata && evdata->data && event == FB_EVENT_BLANK && + ts && ts->client) { + blank = evdata->data; + if (*blank == FB_BLANK_UNBLANK) + goodix_ts_resume(ts); + else if (*blank == FB_BLANK_POWERDOWN) + goodix_ts_suspend(ts); + } + + return 0; +} +#elif defined(CONFIG_HAS_EARLYSUSPEND) +/* + * Function: + * Early suspend function. + * Input: + * h: early_suspend struct. + * Output: + * None. + */ +static void goodix_ts_early_suspend(struct early_suspend *h) +{ + struct goodix_ts_data *ts; + + ts = container_of(h, struct goodix_ts_data, early_suspend); + goodix_ts_suspend(ts); +} + +/* + * Function: + * Late resume function. + * Input: + * h: early_suspend struct. + * Output: + * None. + */ +static void goodix_ts_late_resume(struct early_suspend *h) +{ + struct goodix_ts_data *ts; + + ts = container_of(h, struct goodix_ts_data, early_suspend); + goodix_ts_late_resume(ts); +} #endif +#endif /* !CONFIG_HAS_EARLYSUSPEND && !CONFIG_FB*/ #if GTP_ESD_PROTECT -/******************************************************* -Function: - switch on & off esd delayed work -Input: - client: i2c device - on: SWITCH_ON / SWITCH_OFF -Output: - void -*********************************************************/ +/* + * Function: + * switch on & off esd delayed work + * Input: + * client: i2c device + * on: SWITCH_ON / SWITCH_OFF + * Output: + * void + */ void gtp_esd_switch(struct i2c_client *client, int on) { struct goodix_ts_data *ts; @@ -1749,6 +2192,11 @@ static const struct i2c_device_id goodix_ts_id[] = { { } }; +static const struct of_device_id goodix_match_table[] = { + { .compatible = "goodix,gt9xx", }, + { }, +}; + static struct i2c_driver goodix_ts_driver = { .probe = goodix_ts_probe, .remove = goodix_ts_remove, @@ -1760,6 +2208,7 @@ static struct i2c_driver goodix_ts_driver = { .driver = { .name = GTP_I2C_NAME, .owner = THIS_MODULE, + .of_match_table = goodix_match_table, }, }; diff --git a/drivers/input/touchscreen/gt9xx/gt9xx.h b/drivers/input/touchscreen/gt9xx/gt9xx.h index 48fa2ad2faca..185927c6d2b5 100644 --- a/drivers/input/touchscreen/gt9xx/gt9xx.h +++ b/drivers/input/touchscreen/gt9xx/gt9xx.h @@ -33,7 +33,11 @@ #include <linux/regulator/consumer.h> #include <linux/firmware.h> #include <linux/debugfs.h> -#if defined(CONFIG_HAS_EARLYSUSPEND) + +#if defined(CONFIG_FB) +#include <linux/notifier.h> +#include <linux/fb.h> +#elif defined(CONFIG_HAS_EARLYSUSPEND) #include <linux/earlysuspend.h> #define GOODIX_SUSPEND_LEVEL 1 #endif @@ -43,8 +47,6 @@ struct goodix_ts_platform_data { u32 irq_gpio_flags; int reset_gpio; u32 reset_gpio_flags; - int ldo_en_gpio; - u32 ldo_en_gpio_flags; u32 family_id; u32 x_max; u32 y_max; @@ -56,6 +58,8 @@ struct goodix_ts_platform_data { u32 panel_maxy; bool no_force_update; bool i2c_pull_up; + int gtp_cfg_len; + u8 *config_data; }; struct goodix_ts_data { spinlock_t irq_lock; @@ -65,9 +69,6 @@ struct goodix_ts_data { struct hrtimer timer; struct workqueue_struct *goodix_wq; struct work_struct work; -#if defined(CONFIG_HAS_EARLYSUSPEND) - struct early_suspend early_suspend; -#endif s32 irq_is_disabled; s32 use_irq; u16 abs_x_max; @@ -84,6 +85,14 @@ struct goodix_ts_data { u8 fixed_cfg; u8 esd_running; u8 fw_error; + struct regulator *avdd; + struct regulator *vdd; + struct regulator *vcc_i2c; +#if defined(CONFIG_FB) + struct notifier_block fb_notif; +#elif defined(CONFIG_HAS_EARLYSUSPEND) + struct early_suspend early_suspend; +#endif }; extern u16 show_len; @@ -94,8 +103,8 @@ extern u16 total_len; #define GTP_CHANGE_X2Y 0 #define GTP_DRIVER_SEND_CFG 1 #define GTP_HAVE_TOUCH_KEY 1 -#define GTP_POWER_CTRL_SLEEP 1 -#define GTP_ICS_SLOT_REPORT 0 +#define GTP_POWER_CTRL_SLEEP 0 +#define GTP_ICS_SLOT_REPORT 1 /* auto updated by .bin file as default */ #define GTP_AUTO_UPDATE 0 diff --git a/drivers/misc/qcom/qdsp6v2/audio_utils.c b/drivers/misc/qcom/qdsp6v2/audio_utils.c index cad0220a4960..065b426ca6d0 100644 --- a/drivers/misc/qcom/qdsp6v2/audio_utils.c +++ b/drivers/misc/qcom/qdsp6v2/audio_utils.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2010-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -24,6 +24,15 @@ #include <asm/ioctls.h> #include "audio_utils.h" +/* + * Define maximum buffer size. Below values are chosen considering the higher + * values used among all native drivers. + */ +#define MAX_FRAME_SIZE 1536 +#define MAX_FRAMES 5 +#define META_SIZE (sizeof(struct meta_out_dsp)) +#define MAX_BUFFER_SIZE (1 + ((MAX_FRAME_SIZE + META_SIZE) * MAX_FRAMES)) + static int audio_in_pause(struct q6audio_in *audio) { int rc; @@ -329,6 +338,10 @@ long audio_in_ioctl(struct file *file, rc = -EINVAL; break; } + if (cfg.buffer_size > MAX_BUFFER_SIZE) { + rc = -EINVAL; + break; + } audio->str_cfg.buffer_size = cfg.buffer_size; audio->str_cfg.buffer_count = cfg.buffer_count; if (audio->opened) { diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 38ae877c46e3..3ffb01ff6549 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1203,10 +1203,11 @@ static int proc_getdriver(struct usb_dev_state *ps, void __user *arg) static int proc_connectinfo(struct usb_dev_state *ps, void __user *arg) { - struct usbdevfs_connectinfo ci = { - .devnum = ps->dev->devnum, - .slow = ps->dev->speed == USB_SPEED_LOW - }; + struct usbdevfs_connectinfo ci; + + memset(&ci, 0, sizeof(ci)); + ci.devnum = ps->dev->devnum; + ci.slow = ps->dev->speed == USB_SPEED_LOW; if (copy_to_user(arg, &ci, sizeof(ci))) return -EFAULT; diff --git a/drivers/video/fbdev/msm/mdss.h b/drivers/video/fbdev/msm/mdss.h index 4724f4378e23..609a7aed4977 100644 --- a/drivers/video/fbdev/msm/mdss.h +++ b/drivers/video/fbdev/msm/mdss.h @@ -191,6 +191,7 @@ enum mdss_qos_settings { MDSS_QOS_TS_PREFILL, MDSS_QOS_REMAPPER, MDSS_QOS_IB_NOCR, + MDSS_QOS_WB2_WRITE_GATHER_EN, MDSS_QOS_MAX, }; diff --git a/drivers/video/fbdev/msm/mdss_mdp.c b/drivers/video/fbdev/msm/mdss_mdp.c index cd842cecc945..1b5c1b7d51e1 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.c +++ b/drivers/video/fbdev/msm/mdss_mdp.c @@ -1984,6 +1984,7 @@ static void mdss_mdp_hw_rev_caps_init(struct mdss_data_type *mdata) set_bit(MDSS_QOS_SIMPLIFIED_PREFILL, mdata->mdss_qos_map); set_bit(MDSS_QOS_TS_PREFILL, mdata->mdss_qos_map); set_bit(MDSS_QOS_IB_NOCR, mdata->mdss_qos_map); + set_bit(MDSS_QOS_WB2_WRITE_GATHER_EN, mdata->mdss_qos_map); set_bit(MDSS_CAPS_YUV_CONFIG, mdata->mdss_caps_map); set_bit(MDSS_CAPS_SCM_RESTORE_NOT_REQUIRED, mdata->mdss_caps_map); diff --git a/drivers/video/fbdev/msm/mdss_mdp_hwio.h b/drivers/video/fbdev/msm/mdss_mdp_hwio.h index f54cbb575535..5d8c83126b1b 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_hwio.h +++ b/drivers/video/fbdev/msm/mdss_mdp_hwio.h @@ -829,6 +829,7 @@ enum mdss_mdp_pingpong_index { #define MMSS_VBIF_CLKON 0x4 #define MMSS_VBIF_RD_LIM_CONF 0x0B0 #define MMSS_VBIF_WR_LIM_CONF 0x0C0 +#define MDSS_VBIF_WRITE_GATHER_EN 0x0AC #define MMSS_VBIF_XIN_HALT_CTRL0 0x200 #define MMSS_VBIF_XIN_HALT_CTRL1 0x204 diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c b/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c index 9026b99cd87a..40b10e368309 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_writeback.c @@ -488,6 +488,10 @@ int mdss_mdp_writeback_prepare_cwb(struct mdss_mdp_ctl *ctl, mdss_mdp_writeback_cwb_overflow, sctl); } + if (test_bit(MDSS_QOS_WB2_WRITE_GATHER_EN, ctl->mdata->mdss_qos_map)) + MDSS_VBIF_WRITE(ctl->mdata, MDSS_VBIF_WRITE_GATHER_EN, + BIT(6), false); + if (ctl->mdata->default_ot_wr_limit || ctl->mdata->default_ot_rd_limit) mdss_mdp_set_ot_limit_wb(ctx, false); @@ -907,6 +911,10 @@ static int mdss_mdp_writeback_display(struct mdss_mdp_ctl *ctl, void *arg) return ret; } + if (test_bit(MDSS_QOS_WB2_WRITE_GATHER_EN, ctl->mdata->mdss_qos_map)) + MDSS_VBIF_WRITE(ctl->mdata, MDSS_VBIF_WRITE_GATHER_EN, + BIT(6), false); + mdss_mdp_set_intr_callback(ctx->intr_type, ctx->intf_num, mdss_mdp_writeback_intr_done, ctl); diff --git a/include/dt-bindings/clock/msm-clocks-cobalt.h b/include/dt-bindings/clock/msm-clocks-cobalt.h index 31c4537ea964..b80ea0c31597 100644 --- a/include/dt-bindings/clock/msm-clocks-cobalt.h +++ b/include/dt-bindings/clock/msm-clocks-cobalt.h @@ -157,6 +157,7 @@ #define clk_gcc_usb3_phy_reset 0x03d559f1 #define clk_gcc_usb3phy_phy_reset 0xb1a4f885 #define clk_gcc_aggre1_ufs_axi_clk 0x873459d8 +#define clk_gcc_aggre1_ufs_axi_hw_ctl_clk 0x117a6f39 #define clk_gcc_aggre1_usb3_axi_clk 0xc5c3fbe8 #define clk_gcc_bimc_mss_q6_axi_clk 0x7437988f #define clk_gcc_blsp1_ahb_clk 0x8caa5b4f diff --git a/include/sound/q6asm-v2.h b/include/sound/q6asm-v2.h index dadc2f7a4eae..8525f2e7f738 100644 --- a/include/sound/q6asm-v2.h +++ b/include/sound/q6asm-v2.h @@ -226,7 +226,7 @@ struct audio_client *q6asm_get_audio_client(int session_id); int q6asm_audio_client_buf_alloc(unsigned int dir/* 1:Out,0:In */, struct audio_client *ac, unsigned int bufsz, - unsigned int bufcnt); + uint32_t bufcnt); int q6asm_audio_client_buf_alloc_contiguous(unsigned int dir /* 1:Out,0:In */, struct audio_client *ac, diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c index 20d3f5212323..206fbec249fa 100644 --- a/sound/soc/msm/qdsp6v2/q6asm.c +++ b/sound/soc/msm/qdsp6v2/q6asm.c @@ -1195,7 +1195,7 @@ err: int q6asm_audio_client_buf_alloc(unsigned int dir, struct audio_client *ac, unsigned int bufsz, - unsigned int bufcnt) + uint32_t bufcnt) { int cnt = 0; int rc = 0; @@ -1222,7 +1222,7 @@ int q6asm_audio_client_buf_alloc(unsigned int dir, return 0; } mutex_lock(&ac->cmd_lock); - if (bufcnt > (LONG_MAX/sizeof(struct audio_buffer))) { + if (bufcnt > (U32_MAX/sizeof(struct audio_buffer))) { pr_err("%s: Buffer size overflows", __func__); mutex_unlock(&ac->cmd_lock); goto fail; |
