1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051 |
- /*
- * pt_platform.c
- * Parade TrueTouch(TM) Standard Product Platform Module.
- * For use with Parade touchscreen controllers.
- * Supported parts include:
- * TMA5XX
- * TMA448
- * TMA445A
- * TT21XXX
- * TT31XXX
- * TT4XXXX
- * TT7XXX
- * TC3XXX
- *
- * Copyright (C) 2015-2020 Parade Technologies
- *
- * 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 only version 2, as published by the
- * Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * Contact Parade Technologies at www.paradetech.com <[email protected]>
- */
- #include "pt_regs.h"
- #include "pt_platform.h"
- #ifdef CONFIG_TOUCHSCREEN_PARADE_PLATFORM_FW_UPGRADE
- /* FW for Panel ID = 0x00 */
- #include "pt_fw_pid00.h"
- static struct pt_touch_firmware pt_firmware_pid00 = {
- .img = pt_img_pid00,
- .size = ARRAY_SIZE(pt_img_pid00),
- .ver = pt_ver_pid00,
- .vsize = ARRAY_SIZE(pt_ver_pid00),
- .panel_id = 0x00,
- };
- /* FW for Panel ID = 0x01 */
- #include "pt_fw_pid01.h"
- static struct pt_touch_firmware pt_firmware_pid01 = {
- .img = pt_img_pid01,
- .size = ARRAY_SIZE(pt_img_pid01),
- .ver = pt_ver_pid01,
- .vsize = ARRAY_SIZE(pt_ver_pid01),
- .panel_id = 0x01,
- };
- /* FW for Panel ID not enabled (legacy) */
- #include "pt_fw.h"
- static struct pt_touch_firmware pt_firmware = {
- .img = pt_img,
- .size = ARRAY_SIZE(pt_img),
- .ver = pt_ver,
- .vsize = ARRAY_SIZE(pt_ver),
- };
- #else
- /* FW for Panel ID not enabled (legacy) */
- static struct pt_touch_firmware pt_firmware = {
- .img = NULL,
- .size = 0,
- .ver = NULL,
- .vsize = 0,
- };
- #endif
- #ifdef CONFIG_TOUCHSCREEN_PARADE_PLATFORM_TTCONFIG_UPGRADE
- /* TT Config for Panel ID = 0x00 */
- #include "pt_params_pid00.h"
- static struct touch_settings pt_sett_param_regs_pid00 = {
- .data = (uint8_t *)&pt_param_regs_pid00[0],
- .size = ARRAY_SIZE(pt_param_regs_pid00),
- .tag = 0,
- };
- static struct touch_settings pt_sett_param_size_pid00 = {
- .data = (uint8_t *)&pt_param_size_pid00[0],
- .size = ARRAY_SIZE(pt_param_size_pid00),
- .tag = 0,
- };
- static struct pt_touch_config pt_ttconfig_pid00 = {
- .param_regs = &pt_sett_param_regs_pid00,
- .param_size = &pt_sett_param_size_pid00,
- .fw_ver = ttconfig_fw_ver_pid00,
- .fw_vsize = ARRAY_SIZE(ttconfig_fw_ver_pid00),
- .panel_id = 0x00,
- };
- /* TT Config for Panel ID = 0x01 */
- #include "pt_params_pid01.h"
- static struct touch_settings pt_sett_param_regs_pid01 = {
- .data = (uint8_t *)&pt_param_regs_pid01[0],
- .size = ARRAY_SIZE(pt_param_regs_pid01),
- .tag = 0,
- };
- static struct touch_settings pt_sett_param_size_pid01 = {
- .data = (uint8_t *)&pt_param_size_pid01[0],
- .size = ARRAY_SIZE(pt_param_size_pid01),
- .tag = 0,
- };
- static struct pt_touch_config pt_ttconfig_pid01 = {
- .param_regs = &pt_sett_param_regs_pid01,
- .param_size = &pt_sett_param_size_pid01,
- .fw_ver = ttconfig_fw_ver_pid01,
- .fw_vsize = ARRAY_SIZE(ttconfig_fw_ver_pid01),
- .panel_id = 0x01,
- };
- /* TT Config for Panel ID not enabled (legacy)*/
- #include "pt_params.h"
- static struct touch_settings pt_sett_param_regs = {
- .data = (uint8_t *)&pt_param_regs[0],
- .size = ARRAY_SIZE(pt_param_regs),
- .tag = 0,
- };
- static struct touch_settings pt_sett_param_size = {
- .data = (uint8_t *)&pt_param_size[0],
- .size = ARRAY_SIZE(pt_param_size),
- .tag = 0,
- };
- static struct pt_touch_config pt_ttconfig = {
- .param_regs = &pt_sett_param_regs,
- .param_size = &pt_sett_param_size,
- .fw_ver = ttconfig_fw_ver,
- .fw_vsize = ARRAY_SIZE(ttconfig_fw_ver),
- };
- #else
- /* TT Config for Panel ID not enabled (legacy)*/
- static struct pt_touch_config pt_ttconfig = {
- .param_regs = NULL,
- .param_size = NULL,
- .fw_ver = NULL,
- .fw_vsize = 0,
- };
- #endif
- static struct pt_touch_firmware *pt_firmwares[] = {
- #ifdef CONFIG_TOUCHSCREEN_PARADE_PLATFORM_FW_UPGRADE
- &pt_firmware_pid00,
- &pt_firmware_pid01,
- #endif
- NULL, /* Last item should always be NULL */
- };
- static struct pt_touch_config *pt_ttconfigs[] = {
- #ifdef CONFIG_TOUCHSCREEN_PARADE_PLATFORM_TTCONFIG_UPGRADE
- &pt_ttconfig_pid00,
- &pt_ttconfig_pid01,
- #endif
- NULL, /* Last item should always be NULL */
- };
- struct pt_loader_platform_data _pt_loader_platform_data = {
- .fw = &pt_firmware,
- .ttconfig = &pt_ttconfig,
- .fws = pt_firmwares,
- .ttconfigs = pt_ttconfigs,
- .flags = PT_LOADER_FLAG_NONE,
- };
- /*******************************************************************************
- * FUNCTION: pt_xres
- *
- * SUMMARY: Toggles the reset gpio (TP_XRES) to perform a HW reset
- *
- * RETURN:
- * 0 = success
- * !0 = fail
- *
- * PARAMETERS:
- * *pdata - pointer to the platform data structure
- * *dev - pointer to Device structure
- ******************************************************************************/
- int pt_xres(struct pt_core_platform_data *pdata,
- struct device *dev)
- {
- int rst_gpio = pdata->rst_gpio;
- int rc = 0;
- int ddi_rst_gpio = pdata->ddi_rst_gpio;
- pt_debug(dev, DL_WARN, "%s: 20ms HARD RESET on gpio=%d\n",
- __func__, pdata->rst_gpio);
- /* Toggling only TP_XRES as DDI_XRES resets the entire part */
- gpio_set_value(rst_gpio, 1);
- if (ddi_rst_gpio)
- gpio_set_value(ddi_rst_gpio, 1);
- usleep_range(3000, 4000);
- gpio_set_value(rst_gpio, 0);
- usleep_range(6000, 7000);
- gpio_set_value(rst_gpio, 1);
- if (ddi_rst_gpio)
- gpio_set_value(ddi_rst_gpio, 1);
- /* Sleep to allow the DUT to boot */
- usleep_range(3000, 4000);
- return rc;
- }
- #ifdef PT_PINCTRL_EN
- /*******************************************************************************
- * FUNCTION: pt_pinctrl_init
- *
- * SUMMARY: Pinctrl method to obtain pin state handler for TP_RST, IRQ
- *
- * RETURN:
- * 0 = success
- * !0 = fail
- *
- * PARAMETERS:
- * *pdata - pointer to the platform data structure
- * *dev - pointer to Device structure
- ******************************************************************************/
- static int pt_pinctrl_init(struct pt_core_platform_data *pdata,
- struct device *dev)
- {
- int ret = 0;
- pdata->pinctrl = devm_pinctrl_get(dev);
- if (IS_ERR_OR_NULL(pdata->pinctrl)) {
- pt_debug(dev, DL_ERROR,
- "Failed to get pinctrl, please check dts");
- ret = PTR_ERR(pdata->pinctrl);
- goto err_pinctrl_get;
- }
- pdata->pins_active =
- pinctrl_lookup_state(pdata->pinctrl, "pmx_ts_active");
- if (IS_ERR_OR_NULL(pdata->pins_active)) {
- pt_debug(dev, DL_ERROR, "pmx_ts_active not found");
- ret = PTR_ERR(pdata->pins_active);
- goto err_pinctrl_lookup;
- }
- pdata->pins_suspend =
- pinctrl_lookup_state(pdata->pinctrl, "pmx_ts_suspend");
- if (IS_ERR_OR_NULL(pdata->pins_suspend)) {
- pt_debug(dev, DL_ERROR, "pmx_ts_suspend not found");
- ret = PTR_ERR(pdata->pins_suspend);
- goto err_pinctrl_lookup;
- }
- pdata->pins_release =
- pinctrl_lookup_state(pdata->pinctrl, "pmx_ts_release");
- if (IS_ERR_OR_NULL(pdata->pins_release)) {
- pt_debug(dev, DL_ERROR, "pmx_ts_release not found");
- ret = PTR_ERR(pdata->pins_release);
- goto err_pinctrl_lookup;
- }
- return 0;
- err_pinctrl_lookup:
- devm_pinctrl_put(pdata->pinctrl);
- err_pinctrl_get:
- pdata->pinctrl = NULL;
- pdata->pins_release = NULL;
- pdata->pins_suspend = NULL;
- pdata->pins_active = NULL;
- return ret;
- }
- /*******************************************************************************
- * FUNCTION: pt_pinctrl_select_normal
- *
- * SUMMARY: Pinctrl method to configure drive mode for TP_RST, IRQ - normal
- *
- * RETURN:
- * 0 = success
- * !0 = fail
- *
- * PARAMETERS:
- * *pdata - pointer to the platform data structure
- * *dev - pointer to Device structure
- ******************************************************************************/
- static int pt_pinctrl_select_normal(struct pt_core_platform_data *pdata,
- struct device *dev)
- {
- int ret = 0;
- if (pdata->pinctrl && pdata->pins_active) {
- ret = pinctrl_select_state(pdata->pinctrl, pdata->pins_active);
- if (ret < 0) {
- pt_debug(dev, DL_ERROR, "Set normal pin state error=%d",
- ret);
- }
- }
- return ret;
- }
- /*******************************************************************************
- * FUNCTION: pt_pinctrl_select_suspend
- *
- * SUMMARY: Pinctrl method to configure drive mode for TP_RST, IRQ - suspend
- *
- * RETURN:
- * 0 = success
- * !0 = fail
- *
- * PARAMETERS:
- * *pdata - pointer to the platform data structure
- * *dev - pointer to Device structure
- ******************************************************************************/
- static int pt_pinctrl_select_suspend(struct pt_core_platform_data *pdata,
- struct device *dev)
- {
- int ret = 0;
- if (pdata->pinctrl && pdata->pins_suspend) {
- ret = pinctrl_select_state(pdata->pinctrl, pdata->pins_suspend);
- if (ret < 0) {
- pt_debug(dev, DL_ERROR,
- "Set suspend pin state error=%d", ret);
- }
- }
- return ret;
- }
- /*******************************************************************************
- * FUNCTION: pt_pinctrl_select_release
- *
- * SUMMARY: Pinctrl method to configure drive mode for TP_RST, IRQ - release
- *
- * RETURN:
- * 0 = success
- * !0 = fail
- *
- * PARAMETERS:
- * *pdata - pointer to the platform data structure
- * *dev - pointer to Device structure
- ******************************************************************************/
- static int pt_pinctrl_select_release(struct pt_core_platform_data *pdata,
- struct device *dev)
- {
- int ret = 0;
- if (pdata->pinctrl) {
- if (IS_ERR_OR_NULL(pdata->pins_release)) {
- devm_pinctrl_put(pdata->pinctrl);
- pdata->pinctrl = NULL;
- } else {
- ret = pinctrl_select_state(pdata->pinctrl,
- pdata->pins_release);
- if (ret < 0)
- pt_debug(dev, DL_ERROR,
- "Set gesture pin state error=%d", ret);
- }
- }
- return ret;
- }
- #endif /* PT_PINCTRL_EN */
- /*******************************************************************************
- * FUNCTION: pt_init
- *
- * SUMMARY: Set up/free gpios for TP_RST, IRQ, DDI_RST.
- *
- * RETURN:
- * 0 = success
- * !0 = fail
- *
- * PARAMETERS:
- * *pdata - pointer to the platform data structure
- * on - flag to set up or free gpios(0:free; !0:set up)
- * *dev - pointer to Device structure
- ******************************************************************************/
- int pt_init(struct pt_core_platform_data *pdata,
- int on, struct device *dev)
- {
- int rst_gpio = pdata->rst_gpio;
- int irq_gpio = pdata->irq_gpio;
- int ddi_rst_gpio = pdata->ddi_rst_gpio;
- int rc = 0;
- #ifdef PT_PINCTRL_EN
- if (on) {
- rc = pt_pinctrl_init(pdata, dev);
- if (!rc) {
- pt_pinctrl_select_normal(pdata, dev);
- } else {
- pt_debug(dev, DL_ERROR,
- "%s: Failed to request pinctrl\n", __func__);
- }
- }
- #endif
- if (on && rst_gpio) {
- /* Configure RST GPIO */
- pt_debug(dev, DL_WARN, "%s: Request RST GPIO %d",
- __func__, rst_gpio);
- rc = gpio_request(rst_gpio, NULL);
- if (rc < 0) {
- gpio_free(rst_gpio);
- rc = gpio_request(rst_gpio, NULL);
- }
- if (rc < 0) {
- pt_debug(dev, DL_ERROR,
- "%s: Failed requesting RST GPIO %d\n",
- __func__, rst_gpio);
- goto fail_rst_gpio;
- } else {
- /*
- * Set the GPIO direction and the starting level
- * The start level is high because the DUT needs
- * to stay in reset during power up.
- */
- rc = gpio_direction_output(rst_gpio, 1);
- if (rc < 0) {
- pt_debug(dev, DL_ERROR,
- "%s: Output Setup ERROR: RST GPIO %d\n",
- __func__, rst_gpio);
- goto fail_rst_gpio;
- }
- }
- }
- if (on && irq_gpio) {
- /* Configure IRQ GPIO */
- pt_debug(dev, DL_WARN, "%s: Request IRQ GPIO %d",
- __func__, irq_gpio);
- rc = gpio_request(irq_gpio, NULL);
- if (rc < 0) {
- gpio_free(irq_gpio);
- rc = gpio_request(irq_gpio, NULL);
- }
- if (rc < 0) {
- pt_debug(dev, DL_ERROR,
- "%s: Failed requesting IRQ GPIO %d\n",
- __func__, irq_gpio);
- goto fail_irq_gpio;
- } else {
- /* Set the GPIO direction */
- rc = gpio_direction_input(irq_gpio);
- if (rc < 0) {
- pt_debug(dev, DL_ERROR,
- "%s: Input Setup ERROR: IRQ GPIO %d\n",
- __func__, irq_gpio);
- goto fail_irq_gpio;
- }
- }
- }
- if (on && ddi_rst_gpio) {
- /* Configure DDI RST GPIO */
- pt_debug(dev, DL_WARN, "%s: Request DDI RST GPIO %d",
- __func__, ddi_rst_gpio);
- rc = gpio_request(ddi_rst_gpio, NULL);
- if (rc < 0) {
- gpio_free(ddi_rst_gpio);
- rc = gpio_request(ddi_rst_gpio, NULL);
- }
- if (rc < 0) {
- pt_debug(dev, DL_ERROR,
- "%s: Failed requesting DDI RST GPIO %d\n",
- __func__, ddi_rst_gpio);
- goto fail_ddi_rst_gpio;
- } else {
- /* Set the GPIO direction and the starting level */
- rc = gpio_direction_output(ddi_rst_gpio, 0);
- if (rc < 0) {
- pt_debug(dev, DL_ERROR,
- "%s: Output Setup ERROR: RST GPIO %d\n",
- __func__, ddi_rst_gpio);
- goto fail_ddi_rst_gpio;
- }
- }
- }
- if (!on) {
- /* "on" not set, therefore free all gpio's */
- if (ddi_rst_gpio)
- gpio_free(ddi_rst_gpio);
- if (irq_gpio)
- gpio_free(irq_gpio);
- if (rst_gpio)
- gpio_free(rst_gpio);
- #ifdef PT_PINCTRL_EN
- pt_pinctrl_select_release(pdata, dev);
- #endif
- }
- /* All GPIO's created successfully */
- goto success;
- fail_ddi_rst_gpio:
- pt_debug(dev, DL_ERROR,
- "%s: ERROR - GPIO setup Failure, freeing DDI_XRES GPIO %d\n",
- __func__, ddi_rst_gpio);
- gpio_free(ddi_rst_gpio);
- fail_irq_gpio:
- pt_debug(dev, DL_ERROR,
- "%s: ERROR - GPIO setup Failure, freeing IRQ GPIO %d\n",
- __func__, irq_gpio);
- gpio_free(irq_gpio);
- fail_rst_gpio:
- pt_debug(dev, DL_ERROR,
- "%s: ERROR - GPIO setup Failure, freeing TP_XRES GPIO %d\n",
- __func__, rst_gpio);
- gpio_free(rst_gpio);
- success:
- pt_debug(dev, DL_INFO,
- "%s: SUCCESS - Configured DDI_XRES GPIO %d, IRQ GPIO %d, TP_XRES GPIO %d\n",
- __func__, ddi_rst_gpio, irq_gpio, rst_gpio);
- return rc;
- }
- /*******************************************************************************
- * FUNCTION: pt_wakeup
- *
- * SUMMARY: Resume power for "power on/off" sleep strategy which against to
- * "deepsleep" strategy.
- *
- * RETURN:
- * 0 = success
- * !0 = fail
- *
- * PARAMETERS:
- * *pdata - pointer to the platform data structure
- * *dev - pointer to Device structure
- * *ignore_irq - pointer to atomic structure to allow the host ignoring false
- * IRQ during power up
- ******************************************************************************/
- static int pt_wakeup(struct pt_core_platform_data *pdata,
- struct device *dev, atomic_t *ignore_irq)
- {
- /* Example for TT7XXX */
- int rc = 0;
- #ifdef PT_PINCTRL_EN
- rc = pt_pinctrl_select_normal(pdata, dev);
- if (rc)
- pr_err("%s: GPIO pins activation error: rc=%d\n",
- __func__, rc);
- #endif
- #ifdef TT7XXX_EXAMPLE
- pt_debug(dev, DL_INFO,
- "%s: Enable defined pwr: VDDI, VCC\n", __func__);
- /*
- * Force part into RESET by holding XRES#(TP_XRES)
- * while powering it up
- */
- if (pdata->rst_gpio)
- gpio_set_value(pdata->rst_gpio, 0);
- /* Turn on VDDI [Digital Interface] (+1.8v) */
- if (pdata->vddi_gpio) {
- rc = gpio_request(pdata->vddi_gpio, NULL);
- if (rc < 0) {
- gpio_free(pdata->vddi_gpio);
- rc = gpio_request(pdata->vddi_gpio, NULL);
- }
- if (rc < 0) {
- pr_err("%s: Failed requesting VDDI GPIO %d\n",
- __func__, pdata->vddi_gpio);
- }
- rc = gpio_direction_output(pdata->vddi_gpio, 1);
- if (rc)
- pr_err("%s: setcfg for VDDI GPIO %d failed\n",
- __func__, pdata->vddi_gpio);
- gpio_free(pdata->vddi_gpio);
- usleep_range(3000, 4000);
- }
- /* Turn on VCC */
- if (pdata->vcc_gpio) {
- rc = gpio_request(pdata->vcc_gpio, NULL);
- if (rc < 0) {
- gpio_free(pdata->vcc_gpio);
- rc = gpio_request(pdata->vcc_gpio, NULL);
- }
- if (rc < 0) {
- pr_err("%s: Failed requesting VCC GPIO %d\n",
- __func__, pdata->vcc_gpio);
- }
- rc = gpio_direction_output(pdata->vcc_gpio, 1);
- if (rc)
- pr_err("%s: setcfg for VCC GPIO %d failed\n",
- __func__, pdata->vcc_gpio);
- gpio_free(pdata->vcc_gpio);
- usleep_range(3000, 4000);
- }
- usleep_range(12000, 15000);
- /* Force part out of RESET by releasing XRES#(TP_XRES) */
- if (pdata->rst_gpio)
- gpio_set_value(pdata->rst_gpio, 1);
- #else
- pt_debug(dev, DL_INFO, "%s: Enable defined pwr\n", __func__);
- #endif
- return rc;
- }
- /*******************************************************************************
- * FUNCTION: pt_sleep
- *
- * SUMMARY: Suspend power for "power on/off" sleep strategy which against to
- * "deepsleep" strategy.
- *
- * RETURN:
- * 0 = success
- * !0 = fail
- *
- * PARAMETERS:
- * *pdata - pointer to the platform data structure
- * *dev - pointer to Device structure
- * *ignore_irq - pointer to atomic structure to allow the host ignoring false
- * IRQ during power down
- ******************************************************************************/
- static int pt_sleep(struct pt_core_platform_data *pdata,
- struct device *dev, atomic_t *ignore_irq)
- {
- /* Example for TT7XXX */
- int rc = 0;
- #ifdef TT7XXX_EXAMPLE
- pt_debug(dev, DL_INFO,
- "%s: Turn off defined pwr: VCC, VDDI\n", __func__);
- /*
- * Force part into RESET by holding XRES#(TP_XRES)
- * while powering it up
- */
- if (pdata->rst_gpio)
- gpio_set_value(pdata->rst_gpio, 0);
- /* Turn off VCC */
- if (pdata->vcc_gpio) {
- rc = gpio_request(pdata->vcc_gpio, NULL);
- if (rc < 0) {
- gpio_free(pdata->vcc_gpio);
- rc = gpio_request(pdata->vcc_gpio, NULL);
- }
- if (rc < 0) {
- pr_err("%s: Failed requesting VCC GPIO %d\n",
- __func__, pdata->vcc_gpio);
- }
- rc = gpio_direction_output(pdata->vcc_gpio, 0);
- if (rc)
- pr_err("%s: setcfg for VCC GPIO %d failed\n",
- __func__, pdata->vcc_gpio);
- gpio_free(pdata->vcc_gpio);
- }
- /* Turn off VDDI [Digital Interface] (+1.8v) */
- if (pdata->vddi_gpio) {
- rc = gpio_request(pdata->vddi_gpio, NULL);
- if (rc < 0) {
- gpio_free(pdata->vddi_gpio);
- rc = gpio_request(pdata->vddi_gpio, NULL);
- }
- if (rc < 0) {
- pr_err("%s: Failed requesting VDDI GPIO %d\n",
- __func__, pdata->vddi_gpio);
- }
- rc = gpio_direction_output(pdata->vddi_gpio, 0);
- if (rc)
- pr_err("%s: setcfg for VDDI GPIO %d failed\n",
- __func__, pdata->vddi_gpio);
- gpio_free(pdata->vddi_gpio);
- usleep_range(10000, 12000);
- }
- #else
- pt_debug(dev, DL_INFO, "%s: Turn off defined pwr\n", __func__);
- #endif
- #ifdef PT_PINCTRL_EN
- rc = pt_pinctrl_select_suspend(pdata, dev);
- if (rc)
- pr_err("%s: GPIO pins suspend error: rc=%d\n",
- __func__, rc);
- #endif
- return rc;
- }
- /*******************************************************************************
- * FUNCTION: pt_power
- *
- * SUMMARY: Wrapper function to resume/suspend power with function
- * pt_wakeup()/pt_sleep().
- *
- * RETURN:
- * 0 = success
- * !0 = fail
- *
- * PARAMETERS:
- * *pdata - pointer to the platform data structure
- * on - flag to remsume/suspend power(0:resume; 1:suspend)
- * *dev - pointer to Device structure
- * *ignore_irq - pointer to atomic structure to allow the host ignoring false
- * IRQ during power up/down
- ******************************************************************************/
- int pt_power(struct pt_core_platform_data *pdata,
- int on, struct device *dev, atomic_t *ignore_irq)
- {
- if (on)
- return pt_wakeup(pdata, dev, ignore_irq);
- return pt_sleep(pdata, dev, ignore_irq);
- }
- /*******************************************************************************
- * FUNCTION: pt_irq_stat
- *
- * SUMMARY: Obtain the level state of IRQ gpio.
- *
- * RETURN:
- * level state of IRQ gpio
- *
- * PARAMETERS:
- * *pdata - pointer to the platform data structure
- * *dev - pointer to Device structure
- ******************************************************************************/
- int pt_irq_stat(struct pt_core_platform_data *pdata,
- struct device *dev)
- {
- return gpio_get_value(pdata->irq_gpio);
- }
- #ifdef PT_DETECT_HW
- /*******************************************************************************
- * FUNCTION: pt_detect
- *
- * SUMMARY: Detect the I2C device by reading one byte(FW sentiel) after the
- * reset operation.
- *
- * RETURN:
- * 0 - detected
- * !0 - undetected
- *
- * PARAMETERS:
- * *pdata - pointer to the platform data structure
- * *dev - pointer to Device structure
- * read - pointer to the function to perform a read operation
- ******************************************************************************/
- int pt_detect(struct pt_core_platform_data *pdata,
- struct device *dev, pt_platform_read read)
- {
- int retry = 3;
- int rc;
- char buf[1];
- while (retry--) {
- /* Perform reset, wait for 100 ms and perform read */
- pt_debug(dev, DL_WARN, "%s: Performing a reset\n",
- __func__);
- pdata->xres(pdata, dev);
- msleep(100);
- rc = read(dev, buf, 1);
- if (!rc)
- return 0;
- pt_debug(dev, DL_ERROR, "%s: Read unsuccessful, try=%d\n",
- __func__, 3 - retry);
- }
- return rc;
- }
- #endif
- /*******************************************************************************
- * FUNCTION: pt_setup_power
- *
- * SUMMARY: Turn on/turn off voltage regulator
- *
- * RETURN:
- * 0 = success
- * !0 = failure
- *
- * PARAMETERS:
- * *pdata - pointer to core platform data
- * on - flag to decide power state,PT_MT_POWER_ON/PT_MT_POWER_OFF
- * *dev - pointer to device
- ******************************************************************************/
- int pt_setup_power(struct pt_core_platform_data *pdata, int on,
- struct device *dev)
- {
- int en_vcc = pdata->vcc_gpio;
- int en_vddi = pdata->vddi_gpio;
- int en_avdd = pdata->avdd_gpio;
- int en_avee = pdata->avee_gpio;
- int rc = 0;
- /*
- * For TDDI parts, force part into RESET by holding DDI XRES
- * while powering it up
- */
- if (pdata->ddi_rst_gpio)
- gpio_set_value(pdata->ddi_rst_gpio, 0);
- /*
- * Force part into RESET by holding XRES#(TP_XRES)
- * while powering it up
- */
- if (pdata->rst_gpio)
- gpio_set_value(pdata->rst_gpio, 0);
- if (on == PT_MT_POWER_ON) {
- /*
- * Enable GPIOs to turn on voltage regulators to pwr up DUT
- * - TC device power up order: VDDI, VCC, AVDD, AVEE
- * - TT device power up order: VDDI, VCC
- * NOTE: VDDI must be stable for >10ms before XRES is released
- */
- pt_debug(dev, DL_INFO,
- "%s: Enable defined pwr: VDDI, VCC, AVDD, AVEE\n", __func__);
- /* Turn on VDDI [Digital Interface] (+1.8v) */
- if (pdata->vddi_gpio) {
- rc = gpio_request(en_vddi, NULL);
- if (rc < 0) {
- gpio_free(en_vddi);
- rc = gpio_request(en_vddi, NULL);
- }
- if (rc < 0) {
- pr_err("%s: Failed requesting VDDI GPIO %d\n",
- __func__, en_vddi);
- }
- rc = gpio_direction_output(en_vddi, 1);
- if (rc)
- pr_err("%s: setcfg for VDDI GPIO %d failed\n",
- __func__, en_vddi);
- gpio_free(en_vddi);
- usleep_range(3000, 4000);
- }
- /* Turn on VCC */
- if (pdata->vcc_gpio) {
- rc = gpio_request(en_vcc, NULL);
- if (rc < 0) {
- gpio_free(en_vcc);
- rc = gpio_request(en_vcc, NULL);
- }
- if (rc < 0) {
- pr_err("%s: Failed requesting VCC GPIO %d\n",
- __func__, en_vcc);
- }
- rc = gpio_direction_output(en_vcc, 1);
- if (rc)
- pr_err("%s: setcfg for VCC GPIO %d failed\n",
- __func__, en_vcc);
- gpio_free(en_vcc);
- usleep_range(3000, 4000);
- }
- /* Turn on AVDD (+5.0v) */
- if (pdata->avdd_gpio) {
- rc = gpio_request(en_avdd, NULL);
- if (rc < 0) {
- gpio_free(en_avdd);
- rc = gpio_request(en_avdd, NULL);
- }
- if (rc < 0) {
- pr_err("%s: Failed requesting AVDD GPIO %d\n",
- __func__, en_avdd);
- }
- rc = gpio_direction_output(en_avdd, 1);
- if (rc)
- pr_err("%s: setcfg for AVDD GPIO %d failed\n",
- __func__, en_avdd);
- gpio_free(en_avdd);
- usleep_range(3000, 4000);
- }
- /* Turn on AVEE (-5.0v) */
- if (pdata->avee_gpio) {
- rc = gpio_request(en_avee, NULL);
- if (rc < 0) {
- gpio_free(en_avee);
- rc = gpio_request(en_avee, NULL);
- }
- if (rc < 0) {
- pr_err("%s: Failed requesting AVEE GPIO %d\n",
- __func__, en_avee);
- }
- rc = gpio_direction_output(en_avee, 1);
- if (rc)
- pr_err("%s: setcfg for AVEE GPIO %d failed\n",
- __func__, en_avee);
- gpio_free(en_avee);
- usleep_range(3000, 4000);
- }
- } else {
- /*
- * Disable GPIOs to turn off voltage regulators to pwr down
- * TC device The power down order is: AVEE, AVDD, VDDI
- * TT device The power down order is: VCC, VDDI
- *
- * Note:Turn off some of regulators may effect display
- * parts for TDDI chip
- */
- pt_debug(dev, DL_INFO,
- "%s: Turn off defined pwr: VCC, AVEE, AVDD, VDDI\n", __func__);
- /* Turn off VCC */
- if (pdata->vcc_gpio) {
- rc = gpio_request(en_vcc, NULL);
- if (rc < 0) {
- gpio_free(en_vcc);
- rc = gpio_request(en_vcc, NULL);
- }
- if (rc < 0) {
- pr_err("%s: Failed requesting VCC GPIO %d\n",
- __func__, en_vcc);
- }
- rc = gpio_direction_output(en_vcc, 0);
- if (rc)
- pr_err("%s: setcfg for VCC GPIO %d failed\n",
- __func__, en_vcc);
- gpio_free(en_vcc);
- }
- /* Turn off AVEE (-5.0v) */
- if (pdata->avee_gpio) {
- rc = gpio_request(en_avee, NULL);
- if (rc < 0) {
- gpio_free(en_avee);
- rc = gpio_request(en_avee, NULL);
- }
- if (rc < 0) {
- pr_err("%s: Failed requesting AVEE GPIO %d\n",
- __func__, en_avee);
- }
- rc = gpio_direction_output(en_avee, 0);
- if (rc)
- pr_err("%s: setcfg for AVEE GPIO %d failed\n",
- __func__, en_avee);
- gpio_free(en_avee);
- }
- /* Turn off AVDD (+5.0v) */
- if (pdata->avdd_gpio) {
- rc = gpio_request(en_avdd, NULL);
- if (rc < 0) {
- gpio_free(en_avdd);
- rc = gpio_request(en_avdd, NULL);
- }
- if (rc < 0) {
- pr_err("%s: Failed requesting AVDD GPIO %d\n",
- __func__, en_avdd);
- }
- rc = gpio_direction_output(en_avdd, 0);
- if (rc)
- pr_err("%s: setcfg for AVDD GPIO %d failed\n",
- __func__, en_avdd);
- gpio_free(en_avdd);
- }
- /* Turn off VDDI [Digital Interface] (+1.8v) */
- if (pdata->vddi_gpio) {
- rc = gpio_request(en_vddi, NULL);
- if (rc < 0) {
- gpio_free(en_vddi);
- rc = gpio_request(en_vddi, NULL);
- }
- if (rc < 0) {
- pr_err("%s: Failed requesting VDDI GPIO %d\n",
- __func__, en_vddi);
- }
- rc = gpio_direction_output(en_vddi, 0);
- if (rc)
- pr_err("%s: setcfg for VDDI GPIO %d failed\n",
- __func__, en_vddi);
- gpio_free(en_vddi);
- usleep_range(10000, 12000);
- }
- }
- /* Force part out of RESET by releasing XRES#(TP_XRES) */
- if (pdata->rst_gpio)
- gpio_set_value(pdata->rst_gpio, 1);
- /* Force part out of RESET by releasing DDI XRES */
- if (pdata->ddi_rst_gpio)
- gpio_set_value(pdata->ddi_rst_gpio, 1);
- return rc;
- }
- /*******************************************************************************
- * FUNCTION: pt_setup_irq
- *
- * SUMMARY: Configure the IRQ GPIO used by the TT DUT
- *
- * RETURN:
- * 0 = success
- * !0 = failure
- *
- * PARAMETERS:
- * *pdata - pointer to core platform data
- * on - flag to setup interrupt process work(PT_MT_IRQ_FREE/)
- * *dev - pointer to device
- ******************************************************************************/
- int pt_setup_irq(struct pt_core_platform_data *pdata, int on,
- struct device *dev)
- {
- struct pt_core_data *cd = dev_get_drvdata(dev);
- unsigned long irq_flags;
- int rc = 0;
- if (on == PT_MT_IRQ_REG) {
- /*
- * When TTDL has direct access to the GPIO the irq_stat function
- * will be defined and the gpio_to_irq conversion must be
- * performed. e.g. For CHROMEOS this is not the case, the irq is
- * passed in directly.
- */
- if (pdata->irq_stat) {
- /* Initialize IRQ */
- dev_vdbg(dev, "%s: Value Passed to gpio_to_irq =%d\n",
- __func__, pdata->irq_gpio);
- cd->irq = gpio_to_irq(pdata->irq_gpio);
- dev_vdbg(dev,
- "%s: Value Returned from gpio_to_irq =%d\n",
- __func__, cd->irq);
- }
- if (cd->irq < 0)
- return -EINVAL;
- cd->irq_enabled = true;
- pt_debug(dev, DL_INFO, "%s: initialize threaded irq=%d\n",
- __func__, cd->irq);
- if (pdata->level_irq_udelay > 0)
- /* use level triggered interrupts */
- irq_flags = IRQF_TRIGGER_LOW;
- else
- /* use edge triggered interrupts */
- irq_flags = IRQF_TRIGGER_FALLING;
- rc = request_threaded_irq(cd->irq, NULL, pt_irq,
- irq_flags | IRQF_ONESHOT, dev_name(dev), cd);
- if (rc < 0)
- pt_debug(dev, DL_ERROR,
- "%s: Error, could not request irq\n", __func__);
- } else {
- disable_irq_nosync(cd->irq);
- free_irq(cd->irq, cd);
- }
- return rc;
- }
|