From d8ce2fda5b9632d21296b96c6ea1e3af5c8b23c8 Mon Sep 17 00:00:00 2001 From: Shashi Kant Maurya Date: Fri, 10 Jul 2020 12:37:01 +0530 Subject: include: Fix for compilation issue fix for compilation issue on LA.UM.9.2 sdm660_64 target. Change-Id: I2ea85374e981a3dd26bcdd622ab163b322750398 Signed-off-by: Shashi Kant Maurya --- include/uapi/linux/msm_audio_calibration.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/uapi/linux/msm_audio_calibration.h b/include/uapi/linux/msm_audio_calibration.h index f05f9aaddb70..3da0d0842213 100644 --- a/include/uapi/linux/msm_audio_calibration.h +++ b/include/uapi/linux/msm_audio_calibration.h @@ -99,12 +99,24 @@ enum { AFE_FB_SPKR_PROT_TH_VI_CAL_TYPE, AFE_FB_SPKR_PROT_EX_VI_CAL_TYPE, AFE_SIDETONE_IIR_CAL_TYPE, + AFE_LSM_TOPOLOGY_CAL_TYPE, + AFE_LSM_TX_CAL_TYPE, + ADM_LSM_TOPOLOGY_CAL_TYPE, + ADM_LSM_AUDPROC_CAL_TYPE, + ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE, + ADM_AUDPROC_PERSISTENT_CAL_TYPE, MAX_CAL_TYPES, }; #define AFE_FB_SPKR_PROT_TH_VI_CAL_TYPE AFE_FB_SPKR_PROT_TH_VI_CAL_TYPE #define AFE_FB_SPKR_PROT_EX_VI_CAL_TYPE AFE_FB_SPKR_PROT_EX_VI_CAL_TYPE +#define ADM_AUDPROC_PERSISTENT_CAL_TYPE ADM_AUDPROC_PERSISTENT_CAL_TYPE +#define ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE +#define ADM_LSM_AUDPROC_CAL_TYPE ADM_LSM_AUDPROC_CAL_TYPE +#define AFE_LSM_TOPOLOGY_CAL_TYPE AFE_LSM_TOPOLOGY_CAL_TYPE +#define AFE_LSM_TX_CAL_TYPE AFE_LSM_TX_CAL_TYPE +#define ADM_LSM_AUDPROC_CAL_TYPE ADM_LSM_AUDPROC_CAL_TYPE #define AFE_SIDETONE_IIR_CAL_TYPE AFE_SIDETONE_IIR_CAL_TYPE enum { -- cgit v1.2.3 From 65b27d0fdf66e9d59e50fdd218f0bd6e94206778 Mon Sep 17 00:00:00 2001 From: Akhil P Oommen Date: Thu, 16 Jul 2020 00:49:09 +0530 Subject: msm: kgsl: Mark the scratch buffer as privileged Mark the scratch buffer as privileged so that it can only be accessed by GPU through the ringbuffer. To accomplish this, we need to: 1. Disable the shadow rptr feature. 2. Trigger RPTR update from GPU using a WHERE_AM_I packet. 3. Add support for the new ucode. Change-Id: I9b388f55f53b69028b9bbb2306cb43fd1297c52f Signed-off-by: Akhil P Oommen Signed-off-by: Pranav Patel --- drivers/gpu/msm/adreno.c | 15 +++++++++++- drivers/gpu/msm/adreno.h | 4 +++- drivers/gpu/msm/adreno_a5xx.c | 15 +++++++----- drivers/gpu/msm/adreno_a5xx.h | 4 ++-- drivers/gpu/msm/adreno_pm4types.h | 4 +++- drivers/gpu/msm/adreno_ringbuffer.c | 46 ++++++++++++++++++++++++++++++++++--- drivers/gpu/msm/adreno_ringbuffer.h | 5 +++- 7 files changed, 78 insertions(+), 15 deletions(-) diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c index 000274c5146a..6df074cd2876 100644 --- a/drivers/gpu/msm/adreno.c +++ b/drivers/gpu/msm/adreno.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2002,2007-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2002,2007-2020, 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 @@ -2827,6 +2827,19 @@ static void adreno_resume_device(struct kgsl_device *device) adreno_dispatcher_unhalt(device); } +u32 adreno_get_ucode_version(const u32 *data) +{ + u32 version; + + version = data[1]; + + if ((version & 0xf) != 0xa) + return version; + + version &= ~0xfff; + return version | ((data[3] & 0xfff000) >> 12); +} + static const struct kgsl_functable adreno_functable = { /* Mandatory functions */ .regread = adreno_regread, diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h index 1f598bf3d9f8..5434cfb4083b 100644 --- a/drivers/gpu/msm/adreno.h +++ b/drivers/gpu/msm/adreno.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2008-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2008-2018,2020 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 @@ -942,6 +942,8 @@ int adreno_efuse_read_u32(struct adreno_device *adreno_dev, unsigned int offset, unsigned int *val); void adreno_efuse_unmap(struct adreno_device *adreno_dev); +u32 adreno_get_ucode_version(const u32 *data); + #define ADRENO_TARGET(_name, _id) \ static inline int adreno_is_##_name(struct adreno_device *adreno_dev) \ { \ diff --git a/drivers/gpu/msm/adreno_a5xx.c b/drivers/gpu/msm/adreno_a5xx.c index 2514d13b4cdc..c206bdac7d39 100644 --- a/drivers/gpu/msm/adreno_a5xx.c +++ b/drivers/gpu/msm/adreno_a5xx.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2014-2018,2020 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 @@ -2177,12 +2177,15 @@ static int a5xx_post_start(struct adreno_device *adreno_dev) *cmds++ = 0xF; } - if (adreno_is_preemption_enabled(adreno_dev)) + if (adreno_is_preemption_enabled(adreno_dev)) { cmds += _preemption_init(adreno_dev, rb, cmds, NULL); + rb->_wptr = rb->_wptr - (42 - (cmds - start)); + ret = adreno_ringbuffer_submit_spin_nosync(rb, NULL, 2000); + } else { + rb->_wptr = rb->_wptr - (42 - (cmds - start)); + ret = adreno_ringbuffer_submit_spin(rb, NULL, 2000); + } - rb->_wptr = rb->_wptr - (42 - (cmds - start)); - - ret = adreno_ringbuffer_submit_spin(rb, NULL, 2000); if (ret) spin_idle_debug(KGSL_DEVICE(adreno_dev), "hw initialization failed to idle\n"); @@ -2554,7 +2557,7 @@ static int _load_firmware(struct kgsl_device *device, const char *fwfile, memcpy(ucode->hostptr, &fw->data[4], fw->size - 4); *ucode_size = (fw->size - 4) / sizeof(uint32_t); - *ucode_version = *(unsigned int *)&fw->data[4]; + *ucode_version = adreno_get_ucode_version((u32 *)fw->data); done: release_firmware(fw); diff --git a/drivers/gpu/msm/adreno_a5xx.h b/drivers/gpu/msm/adreno_a5xx.h index 08fd16a83f30..8cfd297fa86d 100644 --- a/drivers/gpu/msm/adreno_a5xx.h +++ b/drivers/gpu/msm/adreno_a5xx.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2015-2016,2020, 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 @@ -112,7 +112,7 @@ void a5xx_crashdump_init(struct adreno_device *adreno_dev); void a5xx_hwcg_set(struct adreno_device *adreno_dev, bool on); -#define A5XX_CP_RB_CNTL_DEFAULT (((ilog2(4) << 8) & 0x1F00) | \ +#define A5XX_CP_RB_CNTL_DEFAULT ((1 << 27) | ((ilog2(4) << 8) & 0x1F00) | \ (ilog2(KGSL_RB_DWORDS >> 1) & 0x3F)) /* GPMU interrupt multiplexor */ #define FW_INTR_INFO (0) diff --git a/drivers/gpu/msm/adreno_pm4types.h b/drivers/gpu/msm/adreno_pm4types.h index ec2c29b929c1..fdd12f571b2e 100644 --- a/drivers/gpu/msm/adreno_pm4types.h +++ b/drivers/gpu/msm/adreno_pm4types.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2002,2007-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2002,2007-2016,2020, 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 @@ -97,6 +97,8 @@ /* A5XX Enable yield in RB only */ #define CP_YIELD_ENABLE 0x1C +#define CP_WHERE_AM_I 0x62 + /* Enable/Disable/Defer A5x global preemption model */ #define CP_PREEMPT_ENABLE_GLOBAL 0x69 diff --git a/drivers/gpu/msm/adreno_ringbuffer.c b/drivers/gpu/msm/adreno_ringbuffer.c index 3a3777823013..475e5e60163d 100644 --- a/drivers/gpu/msm/adreno_ringbuffer.c +++ b/drivers/gpu/msm/adreno_ringbuffer.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2002,2007-2017,2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2002,2007-2017,2019-2020 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 @@ -138,7 +138,7 @@ void adreno_ringbuffer_submit(struct adreno_ringbuffer *rb, adreno_ringbuffer_wptr(adreno_dev, rb); } -int adreno_ringbuffer_submit_spin(struct adreno_ringbuffer *rb, +int adreno_ringbuffer_submit_spin_nosync(struct adreno_ringbuffer *rb, struct adreno_submit_time *time, unsigned int timeout) { struct adreno_device *adreno_dev = ADRENO_RB_DEVICE(rb); @@ -147,6 +147,38 @@ int adreno_ringbuffer_submit_spin(struct adreno_ringbuffer *rb, return adreno_spin_idle(adreno_dev, timeout); } +/* + * adreno_ringbuffer_submit_spin() - Submit the cmds and wait until GPU is idle + * @rb: Pointer to ringbuffer + * @time: Pointer to adreno_submit_time + * @timeout: timeout value in ms + * + * Add commands to the ringbuffer and wait until GPU goes to idle. This routine + * inserts a WHERE_AM_I packet to trigger a shadow rptr update. So, use + * adreno_ringbuffer_submit_spin_nosync() if the previous cmd in the RB is a + * CSY packet because CSY followed by WHERE_AM_I is not legal.. + */ +int adreno_ringbuffer_submit_spin(struct adreno_ringbuffer *rb, + struct adreno_submit_time *time, unsigned int timeout) +{ + struct adreno_device *adreno_dev = ADRENO_RB_DEVICE(rb); + struct kgsl_device *device = KGSL_DEVICE(adreno_dev); + unsigned int *cmds; + + if (adreno_is_a3xx(adreno_dev)) + return adreno_ringbuffer_submit_spin_nosync(rb, time, timeout); + + cmds = adreno_ringbuffer_allocspace(rb, 3); + if (IS_ERR(cmds)) + return PTR_ERR(cmds); + + *cmds++ = cp_packet(adreno_dev, CP_WHERE_AM_I, 2); + cmds += cp_gpuaddr(adreno_dev, cmds, + SCRATCH_RPTR_GPU_ADDR(device, rb->id)); + + return adreno_ringbuffer_submit_spin_nosync(rb, time, timeout); +} + unsigned int *adreno_ringbuffer_allocspace(struct adreno_ringbuffer *rb, unsigned int dwords) { @@ -273,11 +305,12 @@ int adreno_ringbuffer_probe(struct adreno_device *adreno_dev, bool nopreempt) { struct kgsl_device *device = KGSL_DEVICE(adreno_dev); struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev); + unsigned int priv = KGSL_MEMDESC_RANDOM | KGSL_MEMDESC_PRIVILEGED; int i, status; if (!adreno_is_a3xx(adreno_dev)) { status = kgsl_allocate_global(device, &device->scratch, - PAGE_SIZE, 0, KGSL_MEMDESC_RANDOM, "scratch"); + PAGE_SIZE, 0, priv, "scratch"); if (status != 0) return status; } @@ -480,6 +513,8 @@ adreno_ringbuffer_addcmds(struct adreno_ringbuffer *rb, if (gpudev->preemption_post_ibsubmit && adreno_is_preemption_enabled(adreno_dev)) total_sizedwords += 5; + else if (!adreno_is_a3xx(adreno_dev)) + total_sizedwords += 3; /* * a5xx uses 64 bit memory address. pm4 commands that involve read/write @@ -670,6 +705,11 @@ adreno_ringbuffer_addcmds(struct adreno_ringbuffer *rb, adreno_is_preemption_enabled(adreno_dev)) ringcmds += gpudev->preemption_post_ibsubmit(adreno_dev, ringcmds); + else if (!adreno_is_a3xx(adreno_dev)) { + *ringcmds++ = cp_packet(adreno_dev, CP_WHERE_AM_I, 2); + ringcmds += cp_gpuaddr(adreno_dev, ringcmds, + SCRATCH_RPTR_GPU_ADDR(device, rb->id)); + } /* * If we have more ringbuffer commands than space reserved diff --git a/drivers/gpu/msm/adreno_ringbuffer.h b/drivers/gpu/msm/adreno_ringbuffer.h index d64ccbdc846c..a2bf92acf4af 100644 --- a/drivers/gpu/msm/adreno_ringbuffer.h +++ b/drivers/gpu/msm/adreno_ringbuffer.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2002,2007-2016,2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2002,2007-2016,2019-2020 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 @@ -172,6 +172,9 @@ int adreno_ringbuffer_issuecmds(struct adreno_ringbuffer *rb, void adreno_ringbuffer_submit(struct adreno_ringbuffer *rb, struct adreno_submit_time *time); +int adreno_ringbuffer_submit_spin_nosync(struct adreno_ringbuffer *rb, + struct adreno_submit_time *time, unsigned int timeout); + int adreno_ringbuffer_submit_spin(struct adreno_ringbuffer *rb, struct adreno_submit_time *time, unsigned int timeout); -- cgit v1.2.3 From 147458119bb26f6bb0fc24e28dbdeadb4fd9ceaf Mon Sep 17 00:00:00 2001 From: Shashi Kant Maurya Date: Wed, 5 Aug 2020 12:45:12 +0530 Subject: Revert "include: Fix for compilation issue" This reverts commit 769b5eb47768ecc0662f02a7b42ec323df2841ab. These cal types are not supported. Change-Id: Iec7d2c171c49e6e1fc4562d13d111dcdc52523fe Signed-off-by: Shashi Kant Maurya Signed-off-by: Rajshekar Eashwarappa --- include/uapi/linux/msm_audio_calibration.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/include/uapi/linux/msm_audio_calibration.h b/include/uapi/linux/msm_audio_calibration.h index 3da0d0842213..f05f9aaddb70 100644 --- a/include/uapi/linux/msm_audio_calibration.h +++ b/include/uapi/linux/msm_audio_calibration.h @@ -99,24 +99,12 @@ enum { AFE_FB_SPKR_PROT_TH_VI_CAL_TYPE, AFE_FB_SPKR_PROT_EX_VI_CAL_TYPE, AFE_SIDETONE_IIR_CAL_TYPE, - AFE_LSM_TOPOLOGY_CAL_TYPE, - AFE_LSM_TX_CAL_TYPE, - ADM_LSM_TOPOLOGY_CAL_TYPE, - ADM_LSM_AUDPROC_CAL_TYPE, - ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE, - ADM_AUDPROC_PERSISTENT_CAL_TYPE, MAX_CAL_TYPES, }; #define AFE_FB_SPKR_PROT_TH_VI_CAL_TYPE AFE_FB_SPKR_PROT_TH_VI_CAL_TYPE #define AFE_FB_SPKR_PROT_EX_VI_CAL_TYPE AFE_FB_SPKR_PROT_EX_VI_CAL_TYPE -#define ADM_AUDPROC_PERSISTENT_CAL_TYPE ADM_AUDPROC_PERSISTENT_CAL_TYPE -#define ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE -#define ADM_LSM_AUDPROC_CAL_TYPE ADM_LSM_AUDPROC_CAL_TYPE -#define AFE_LSM_TOPOLOGY_CAL_TYPE AFE_LSM_TOPOLOGY_CAL_TYPE -#define AFE_LSM_TX_CAL_TYPE AFE_LSM_TX_CAL_TYPE -#define ADM_LSM_AUDPROC_CAL_TYPE ADM_LSM_AUDPROC_CAL_TYPE #define AFE_SIDETONE_IIR_CAL_TYPE AFE_SIDETONE_IIR_CAL_TYPE enum { -- cgit v1.2.3 From 80dacd65009f1dc73558ff1d30637e2cc83b0855 Mon Sep 17 00:00:00 2001 From: Udipto Goswami Date: Wed, 16 Sep 2020 17:20:10 +0530 Subject: usb: dwc3: ep0: Return from handle_status if ep0_delegate_req succeeds Currently if the controller receives a standard interface request like 0x81 it goes to ep0_inspect_setup where on the basis of bRequestType it calls ep0_std_request which calls handle_status. Since it is an interface request, it will further call delegate_request which is handles in composite_setup and calls ep0_queue. However, in the implementation of handle_status we have an if check for return value of delegate request. If it returns zero then instead of bailing out from there we break from the switch and go to the return statement of handle_status, which is ep0_queue. This results in queuing the same request two times resulting in a list corruption due to double add. Fix this by returning from handle_status irrespective of the return status as in case ep0_queue fails we are suppose to bail out without doing anything. Change-Id: Ibfc99e9112b1173f2a22007a5e18b458904cefca Signed-off-by: Udipto Goswami --- drivers/usb/dwc3/ep0.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index 1633807aee36..ce3e1f11cbc5 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -415,9 +415,7 @@ static int dwc3_ep0_handle_status(struct dwc3 *dwc, */ ret = dwc3_ep0_delegate_req(dwc, ctrl); - if (ret) - return ret; - break; + return ret; case USB_RECIP_ENDPOINT: dep = dwc3_wIndex_to_dep(dwc, ctrl->wIndex); -- cgit v1.2.3 From 2a4121e99aa617ce000fa843197d304a37292c10 Mon Sep 17 00:00:00 2001 From: VijayaKumar T M Date: Fri, 16 Oct 2020 20:52:30 +0530 Subject: msm: isp2: fix close sequence of isp stats stream Stats stream close is failing due to wrong array index(2) for rear camera which uses dual vfe. Change-Id: I26a0e1289f033aaad62cca24b064f1b0bf2788e2 Signed-off-by: VijayaKumar T M --- drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c index 3e8220005f77..4ffd6e4e54e0 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2018, 2020 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 @@ -548,10 +548,10 @@ int msm_isp_release_stats_stream(struct vfe_device *vfe_dev, void *arg) stream_info->buffer_offset[i] = stream_info->buffer_offset[k]; } + stream_info->num_isp--; stream_info->vfe_dev[stream_info->num_isp] = 0; stream_info->stream_handle[stream_info->num_isp] = 0; stream_info->buffer_offset[stream_info->num_isp] = 0; - stream_info->num_isp--; stream_info->vfe_mask &= ~(1 << vfe_dev->pdev->id); if (stream_info->num_isp == 0) stream_info->state = STATS_AVAILABLE; -- cgit v1.2.3 From 31369983e1e91218c2d3d000f920388d149efed2 Mon Sep 17 00:00:00 2001 From: Shashi Kant Maurya Date: Sun, 1 Nov 2020 22:18:08 +0530 Subject: soc: add proxy ports for call screening in machine driver add machine driver changes for proxy port changes. Change-Id: Ic784bc7334ae5e4fca6a0ca7cbade4c35c48b302 Signed-off-by: Shashi Kant Maurya --- sound/soc/msm/msm8998.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/sound/soc/msm/msm8998.c b/sound/soc/msm/msm8998.c index 8b3da6d7dd64..e48b23dffe61 100644 --- a/sound/soc/msm/msm8998.c +++ b/sound/soc/msm/msm8998.c @@ -7516,6 +7516,33 @@ static struct snd_soc_dai_link msm_common_be_dai_links[] = { .be_hw_params_fixup = msm_be_hw_params_fixup, .ignore_suspend = 1, }, + /* Proxy Tx BACK END DAI Link */ + { + .name = LPASS_BE_PROXY_TX, + .stream_name = "Proxy Capture", + .cpu_dai_name = "msm-dai-q6-dev.8195", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-tx", + .no_pcm = 1, + .dpcm_capture = 1, + .be_id = MSM_BACKEND_DAI_PROXY_TX, + .ignore_suspend = 1, + }, + /* Proxy Rx BACK END DAI Link */ + { + .name = LPASS_BE_PROXY_RX, + .stream_name = "Proxy Playback", + .cpu_dai_name = "msm-dai-q6-dev.8194", + .platform_name = "msm-pcm-routing", + .codec_name = "msm-stub-codec.1", + .codec_dai_name = "msm-stub-rx", + .no_pcm = 1, + .dpcm_playback = 1, + .be_id = MSM_BACKEND_DAI_PROXY_RX, + .ignore_pmdown_time = 1, + .ignore_suspend = 1, + }, { .name = LPASS_BE_USB_AUDIO_RX, .stream_name = "USB Audio Playback", -- cgit v1.2.3 From 466480a9e622f3e81d3f0c0aa33b7747b7137338 Mon Sep 17 00:00:00 2001 From: Chirag Khurana Date: Wed, 9 Sep 2020 12:37:36 +0530 Subject: mdss_hdmi_tx: reset HDR flags on disconnect HDR related flags are reset at disconnect event to handle proper HDR colorimetry transition during connect and disconnect events. Change-Id: I8b95b6f4635052446ab5fd707227b2bbe6038c7c Signed-off-by: Chirag Khurana --- drivers/video/fbdev/msm/mdss_hdmi_tx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.c b/drivers/video/fbdev/msm/mdss_hdmi_tx.c index 747c245bf78e..0862e1229b4c 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_tx.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.c @@ -3432,6 +3432,9 @@ static int hdmi_tx_power_off(struct hdmi_tx_ctrl *hdmi_ctrl) hdmi_ctrl->panel_power_on = false; hdmi_ctrl->vic = 0; + hdmi_ctrl->use_bt2020 = false; + hdmi_ctrl->curr_hdr_state = HDR_DISABLE; + if (hdmi_ctrl->hpd_off_pending || hdmi_ctrl->panel_suspend) hdmi_tx_hpd_off(hdmi_ctrl); -- cgit v1.2.3 From b78e7891460c591ccadc44baf83bd8982fd4fba5 Mon Sep 17 00:00:00 2001 From: Tanwee Kausar Date: Tue, 13 Oct 2020 09:56:07 -0700 Subject: crypto: Fix possible stack out of bound error Adding fix to check upper limit on the length of the destination array while copying element from source address to avoid stack out of bound error. Change-Id: I71ab7c8045f300623e4d906a764940dbcc88c878 Signed-off-by: Tanwee Kausar --- drivers/crypto/msm/qce.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/crypto/msm/qce.c b/drivers/crypto/msm/qce.c index 4cf95b90a2df..53c07aacc145 100644 --- a/drivers/crypto/msm/qce.c +++ b/drivers/crypto/msm/qce.c @@ -1,6 +1,6 @@ /* Qualcomm Crypto Engine driver. * - * Copyright (c) 2010-2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2010-2016, 2020 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 @@ -768,6 +768,11 @@ static int _ce_setup(struct qce_device *pce_dev, struct qce_req *q_req, switch (q_req->alg) { case CIPHER_ALG_DES: if (q_req->mode != QCE_MODE_ECB) { + if (ivsize > MAX_IV_LENGTH) { + pr_err("%s: error: Invalid length parameter\n", + __func__); + return -EINVAL; + } _byte_stream_to_net_words(enciv32, q_req->iv, ivsize); writel_relaxed(enciv32[0], pce_dev->iobase + CRYPTO_CNTR0_IV0_REG); -- cgit v1.2.3 From 5debc0eac4b6946f2bfb289f87e7b52f6c9bc56d Mon Sep 17 00:00:00 2001 From: Todd Kjos Date: Mon, 20 Jul 2020 21:14:33 -0700 Subject: binder: fix UAF when releasing todo list When releasing a thread todo list when tearing down a binder_proc, the following race was possible which could result in a use-after-free: 1. Thread 1: enter binder_release_work from binder_thread_release 2. Thread 2: binder_update_ref_for_handle() calls binder_dec_node_ilocked() 3. Thread 2: dec nodeA --> 0 (will free node) 4. Thread 1: ACQ inner_proc_lock 5. Thread 2: block on inner_proc_lock 6. Thread 1: dequeue work (BINDER_WORK_NODE, part of nodeA) 7. Thread 1: REL inner_proc_lock 8. Thread 2: ACQ inner_proc_lock 9. Thread 2: todo list cleanup, but work was already dequeued 10. Thread 2: free node 11. Thread 2: REL inner_proc_lock 12. Thread 1: deref w->type (UAF) The problem was that for a BINDER_WORK_NODE, the binder_work element must not be accessed after releasing the inner_proc_lock while processing the todo list elements since another thread might be handling a deref on the node containing the binder_work element leading to the node being freed. Bug: 161151868 Signed-off-by: Todd Kjos Change-Id: I4ae752abfe1aa38872be6f266ddd271802952625 Git-repo: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git Git-commit: cebe72f19bebdee8fc9f1b31dd21a88a259ff419 Signed-off-by: Alam Md Danish Signed-off-by: Rahul Shahare --- drivers/android/binder.c | 35 ++++++++++------------------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 9fa18e8f25ac..f0544e72aa2b 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -284,7 +284,7 @@ struct binder_device { struct binder_work { struct list_head entry; - enum { + enum binder_work_type { BINDER_WORK_TRANSACTION = 1, BINDER_WORK_TRANSACTION_COMPLETE, BINDER_WORK_RETURN_ERROR, @@ -921,27 +921,6 @@ static struct binder_work *binder_dequeue_work_head_ilocked( return w; } -/** - * binder_dequeue_work_head() - Dequeues the item at head of list - * @proc: binder_proc associated with list - * @list: list to dequeue head - * - * Removes the head of the list if there are items on the list - * - * Return: pointer dequeued binder_work, NULL if list was empty - */ -static struct binder_work *binder_dequeue_work_head( - struct binder_proc *proc, - struct list_head *list) -{ - struct binder_work *w; - - binder_inner_proc_lock(proc); - w = binder_dequeue_work_head_ilocked(list); - binder_inner_proc_unlock(proc); - return w; -} - static void binder_defer_work(struct binder_proc *proc, enum binder_deferred_state defer); static void binder_free_thread(struct binder_thread *thread); @@ -4442,13 +4421,17 @@ static void binder_release_work(struct binder_proc *proc, struct list_head *list) { struct binder_work *w; + enum binder_work_type wtype; while (1) { - w = binder_dequeue_work_head(proc, list); + binder_inner_proc_lock(proc); + w = binder_dequeue_work_head_ilocked(list); + wtype = w ? w->type : 0; + binder_inner_proc_unlock(proc); if (!w) return; - switch (w->type) { + switch (wtype) { case BINDER_WORK_TRANSACTION: { struct binder_transaction *t; @@ -4482,9 +4465,11 @@ static void binder_release_work(struct binder_proc *proc, kfree(death); binder_stats_deleted(BINDER_STAT_DEATH); } break; + case BINDER_WORK_NODE: + break; default: pr_err("unexpected work type, %d, not freed\n", - w->type); + wtype); break; } } -- cgit v1.2.3 From 703cccfc832e2c42abdfb3eb03e7645059f0b7c2 Mon Sep 17 00:00:00 2001 From: Archana Sriram Date: Sun, 18 Oct 2020 23:34:04 +0530 Subject: msm: kgsl: Compare pid pointer instead of TGID for a new process There is a possibility of sharing process_private between two unrelated processes due to PID wrapping. In kgsl_process_private_new(), instead of checking numeric TGID, compare the unique pid pointer of the current process with that of the existing processes in kgsl process list to allow sharing of process_private data judiciously. Also, in all required functions get TGID/PID of a process from its struct pid. Change-Id: I0e3d5d79275cdb3f3c304fb36322ad56b0d0b227 Signed-off-by: Archana Sriram Signed-off-by: Kamal Agrawal --- drivers/gpu/msm/adreno_debugfs.c | 4 ++-- drivers/gpu/msm/adreno_dispatch.c | 4 ++-- drivers/gpu/msm/adreno_profile.c | 4 ++-- drivers/gpu/msm/kgsl.c | 30 +++++++++++++++++++----------- drivers/gpu/msm/kgsl_debugfs.c | 9 +++++---- drivers/gpu/msm/kgsl_device.h | 8 ++++---- drivers/gpu/msm/kgsl_iommu.c | 4 ++-- drivers/gpu/msm/kgsl_sharedmem.c | 4 ++-- drivers/gpu/msm/kgsl_trace.h | 10 +++++----- 9 files changed, 43 insertions(+), 34 deletions(-) diff --git a/drivers/gpu/msm/adreno_debugfs.c b/drivers/gpu/msm/adreno_debugfs.c index 2027ac66f737..201e63f5e9dc 100644 --- a/drivers/gpu/msm/adreno_debugfs.c +++ b/drivers/gpu/msm/adreno_debugfs.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2002,2008-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2002,2008-2017,2020, 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 @@ -281,7 +281,7 @@ static int ctx_print(struct seq_file *s, void *unused) ctx_type_str(drawctxt->type), drawctxt->base.priority, drawctxt->base.proc_priv->comm, - drawctxt->base.proc_priv->pid, + pid_nr(drawctxt->base.proc_priv->pid), drawctxt->base.tid); seq_puts(s, "flags: "); diff --git a/drivers/gpu/msm/adreno_dispatch.c b/drivers/gpu/msm/adreno_dispatch.c index 49b14fbf439c..3eca9bdcaaf7 100644 --- a/drivers/gpu/msm/adreno_dispatch.c +++ b/drivers/gpu/msm/adreno_dispatch.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2020, 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 @@ -1695,7 +1695,7 @@ static inline const char *_kgsl_context_comm(struct kgsl_context *context) #define pr_fault(_d, _c, fmt, args...) \ dev_err((_d)->dev, "%s[%d]: " fmt, \ _kgsl_context_comm((_c)->context), \ - (_c)->context->proc_priv->pid, ##args) + pid_nr((_c)->context->proc_priv->pid), ##args) static void adreno_fault_header(struct kgsl_device *device, diff --git a/drivers/gpu/msm/adreno_profile.c b/drivers/gpu/msm/adreno_profile.c index e756c82287fd..93501d96ef8e 100644 --- a/drivers/gpu/msm/adreno_profile.c +++ b/drivers/gpu/msm/adreno_profile.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2016, 2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2016, 2018,2020, 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 @@ -168,7 +168,7 @@ static int _build_pre_ib_cmds(struct adreno_device *adreno_dev, ibcmds += _ib_cmd_mem_write(adreno_dev, ibcmds, gpuaddr + data_offset, drawctxt->base.id, &data_offset); ibcmds += _ib_cmd_mem_write(adreno_dev, ibcmds, gpuaddr + data_offset, - drawctxt->base.proc_priv->pid, &data_offset); + pid_nr(drawctxt->base.proc_priv->pid), &data_offset); ibcmds += _ib_cmd_mem_write(adreno_dev, ibcmds, gpuaddr + data_offset, drawctxt->base.tid, &data_offset); ibcmds += _ib_cmd_mem_write(adreno_dev, ibcmds, gpuaddr + data_offset, diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index e081e579d142..9d9836052158 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -540,7 +540,7 @@ int kgsl_context_init(struct kgsl_device_private *dev_priv, if (atomic_read(&proc_priv->ctxt_count) > KGSL_MAX_CONTEXTS_PER_PROC) { KGSL_DRV_ERR_RATELIMIT(device, "Per process context limit reached for pid %u", - dev_priv->process_priv->pid); + pid_nr(dev_priv->process_priv->pid)); spin_unlock(&proc_priv->ctxt_count_lock); return -ENOSPC; } @@ -865,6 +865,7 @@ static void kgsl_destroy_process_private(struct kref *kref) struct kgsl_process_private *private = container_of(kref, struct kgsl_process_private, refcount); + put_pid(private->pid); idr_destroy(&private->mem_idr); idr_destroy(&private->syncsource_idr); @@ -895,7 +896,7 @@ struct kgsl_process_private *kgsl_process_private_find(pid_t pid) mutex_lock(&kgsl_driver.process_mutex); list_for_each_entry(p, &kgsl_driver.process_list, list) { - if (p->pid == pid) { + if (pid_nr(p->pid) == pid) { if (kgsl_process_private_get(p)) private = p; break; @@ -909,13 +910,15 @@ static struct kgsl_process_private *kgsl_process_private_new( struct kgsl_device *device) { struct kgsl_process_private *private; - pid_t tgid = task_tgid_nr(current); + struct pid *cur_pid = get_task_pid(current->group_leader, PIDTYPE_PID); /* Search in the process list */ list_for_each_entry(private, &kgsl_driver.process_list, list) { - if (private->pid == tgid) { - if (!kgsl_process_private_get(private)) + if (private->pid == cur_pid) { + if (!kgsl_process_private_get(private)) { + put_pid(cur_pid); private = ERR_PTR(-EINVAL); + } return private; } } @@ -927,7 +930,7 @@ static struct kgsl_process_private *kgsl_process_private_new( kref_init(&private->refcount); - private->pid = tgid; + private->pid = cur_pid; get_task_comm(private->comm, current->group_leader); spin_lock_init(&private->mem_lock); @@ -938,12 +941,14 @@ static struct kgsl_process_private *kgsl_process_private_new( idr_init(&private->syncsource_idr); /* Allocate a pagetable for the new process object */ - private->pagetable = kgsl_mmu_getpagetable(&device->mmu, tgid); + private->pagetable = kgsl_mmu_getpagetable(&device->mmu, + pid_nr(cur_pid)); if (IS_ERR(private->pagetable)) { int err = PTR_ERR(private->pagetable); idr_destroy(&private->mem_idr); idr_destroy(&private->syncsource_idr); + put_pid(private->pid); kfree(private); private = ERR_PTR(err); @@ -1877,8 +1882,9 @@ static long gpumem_free_entry(struct kgsl_mem_entry *entry) if (entry->memdesc.pagetable != NULL) ptname = entry->memdesc.pagetable->name; - kgsl_memfree_add(entry->priv->pid, ptname, entry->memdesc.gpuaddr, - entry->memdesc.size, entry->memdesc.flags); + kgsl_memfree_add(pid_nr(entry->priv->pid), ptname, + entry->memdesc.gpuaddr, entry->memdesc.size, + entry->memdesc.flags); kgsl_mem_entry_put(entry); @@ -4529,13 +4535,15 @@ kgsl_get_unmapped_area(struct file *file, unsigned long addr, if (IS_ERR_VALUE(val)) KGSL_DRV_ERR_RATELIMIT(device, "get_unmapped_area: pid %d addr %lx pgoff %lx len %ld failed error %d\n", - private->pid, addr, pgoff, len, (int) val); + pid_nr(private->pid), addr, + pgoff, len, (int) val); } else { val = _get_svm_area(private, entry, addr, len, flags); if (IS_ERR_VALUE(val)) KGSL_DRV_ERR_RATELIMIT(device, "_get_svm_area: pid %d mmap_base %lx addr %lx pgoff %lx len %ld failed error %d\n", - private->pid, current->mm->mmap_base, addr, + pid_nr(private->pid), + current->mm->mmap_base, addr, pgoff, len, (int) val); } diff --git a/drivers/gpu/msm/kgsl_debugfs.c b/drivers/gpu/msm/kgsl_debugfs.c index 592257a332d1..30769de41a70 100644 --- a/drivers/gpu/msm/kgsl_debugfs.c +++ b/drivers/gpu/msm/kgsl_debugfs.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2002,2008-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2002,2008-2017,2020, 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 @@ -393,7 +393,7 @@ void kgsl_process_init_debugfs(struct kgsl_process_private *private) unsigned char name[16]; struct dentry *dentry; - snprintf(name, sizeof(name), "%d", private->pid); + snprintf(name, sizeof(name), "%d", pid_nr(private->pid)); private->debug_root = debugfs_create_dir(name, proc_d_debugfs); @@ -413,14 +413,15 @@ void kgsl_process_init_debugfs(struct kgsl_process_private *private) } dentry = debugfs_create_file("mem", 0444, private->debug_root, - (void *) ((unsigned long) private->pid), &process_mem_fops); + (void *) ((unsigned long) pid_nr(private->pid)), + &process_mem_fops); if (IS_ERR_OR_NULL(dentry)) WARN((dentry == NULL), "Unable to create 'mem' file for %s\n", name); dentry = debugfs_create_file("sparse_mem", 0444, private->debug_root, - (void *) ((unsigned long) private->pid), + (void *) ((unsigned long) pid_nr(private->pid)), &process_sparse_mem_fops); if (IS_ERR_OR_NULL(dentry)) diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h index 0ab6041b3bbd..14852326116c 100644 --- a/drivers/gpu/msm/kgsl_device.h +++ b/drivers/gpu/msm/kgsl_device.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2002,2007-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2002,2007-2020, 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 @@ -405,13 +405,13 @@ struct kgsl_context { #define pr_context(_d, _c, fmt, args...) \ dev_err((_d)->dev, "%s[%d]: " fmt, \ _context_comm((_c)), \ - (_c)->proc_priv->pid, ##args) + pid_nr((_c)->proc_priv->pid), ##args) /** * struct kgsl_process_private - Private structure for a KGSL process (across * all devices) * @priv: Internal flags, use KGSL_PROCESS_* values - * @pid: ID for the task owner of the process + * @pid: Identification structure for the task owner of the process * @comm: task name of the process * @mem_lock: Spinlock to protect the process memory lists * @refcount: kref object for reference counting the process @@ -428,7 +428,7 @@ struct kgsl_context { */ struct kgsl_process_private { unsigned long priv; - pid_t pid; + struct pid *pid; char comm[TASK_COMM_LEN]; spinlock_t mem_lock; struct kref refcount; diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c index f6ff4658c93b..aff54105474a 100644 --- a/drivers/gpu/msm/kgsl_iommu.c +++ b/drivers/gpu/msm/kgsl_iommu.c @@ -692,7 +692,7 @@ static void _get_entries(struct kgsl_process_private *private, prev->flags = p->memdesc.flags; prev->priv = p->memdesc.priv; prev->pending_free = p->pending_free; - prev->pid = private->pid; + prev->pid = pid_nr(private->pid); __kgsl_get_memory_usage(prev); } @@ -702,7 +702,7 @@ static void _get_entries(struct kgsl_process_private *private, next->flags = n->memdesc.flags; next->priv = n->memdesc.priv; next->pending_free = n->pending_free; - next->pid = private->pid; + next->pid = pid_nr(private->pid); __kgsl_get_memory_usage(next); } } diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c index 4c54553e9977..b233211620da 100644 --- a/drivers/gpu/msm/kgsl_sharedmem.c +++ b/drivers/gpu/msm/kgsl_sharedmem.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2002,2007-2017 The Linux Foundation. All rights reserved. +/* Copyright (c) 2002,2007-2017,2020, 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 @@ -202,7 +202,7 @@ void kgsl_process_init_sysfs(struct kgsl_device *device, /* Keep private valid until the sysfs enries are removed. */ kgsl_process_private_get(private); - snprintf(name, sizeof(name), "%d", private->pid); + snprintf(name, sizeof(name), "%d", pid_nr(private->pid)); if (kobject_init_and_add(&private->kobj, &ktype_mem_entry, kgsl_driver.prockobj, name)) { diff --git a/drivers/gpu/msm/kgsl_trace.h b/drivers/gpu/msm/kgsl_trace.h index 6438c6e65b97..2d9bca7e7d7f 100644 --- a/drivers/gpu/msm/kgsl_trace.h +++ b/drivers/gpu/msm/kgsl_trace.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved. +/* Copyright (c) 2011-2016,2020, 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 @@ -417,7 +417,7 @@ TRACE_EVENT(kgsl_mem_alloc, TP_fast_assign( __entry->gpuaddr = mem_entry->memdesc.gpuaddr; __entry->size = mem_entry->memdesc.size; - __entry->tgid = mem_entry->priv->pid; + __entry->tgid = pid_nr(mem_entry->priv->pid); kgsl_get_memory_usage(__entry->usage, sizeof(__entry->usage), mem_entry->memdesc.flags); __entry->id = mem_entry->id; @@ -510,7 +510,7 @@ TRACE_EVENT(kgsl_mem_map, __entry->size = mem_entry->memdesc.size; __entry->fd = fd; __entry->type = kgsl_memdesc_usermem_type(&mem_entry->memdesc); - __entry->tgid = mem_entry->priv->pid; + __entry->tgid = pid_nr(mem_entry->priv->pid); kgsl_get_memory_usage(__entry->usage, sizeof(__entry->usage), mem_entry->memdesc.flags); __entry->id = mem_entry->id; @@ -545,7 +545,7 @@ TRACE_EVENT(kgsl_mem_free, __entry->gpuaddr = mem_entry->memdesc.gpuaddr; __entry->size = mem_entry->memdesc.size; __entry->type = kgsl_memdesc_usermem_type(&mem_entry->memdesc); - __entry->tgid = mem_entry->priv->pid; + __entry->tgid = pid_nr(mem_entry->priv->pid); kgsl_get_memory_usage(__entry->usage, sizeof(__entry->usage), mem_entry->memdesc.flags); __entry->id = mem_entry->id; @@ -580,7 +580,7 @@ TRACE_EVENT(kgsl_mem_sync_cache, __entry->gpuaddr = mem_entry->memdesc.gpuaddr; kgsl_get_memory_usage(__entry->usage, sizeof(__entry->usage), mem_entry->memdesc.flags); - __entry->tgid = mem_entry->priv->pid; + __entry->tgid = pid_nr(mem_entry->priv->pid); __entry->id = mem_entry->id; __entry->op = op; __entry->offset = offset; -- cgit v1.2.3 From dfb161642804efbcfdd674f20150e0532b7dae01 Mon Sep 17 00:00:00 2001 From: Narender Ankam Date: Thu, 17 Sep 2020 13:37:00 +0530 Subject: msm: mdss: hdmi: parse physical screen dimensions from EDID Parse Basic Display Parameters/Features of EDID and store Horizontal and Vertical Screen size of downstream HDMI sink. Change-Id: Ic538a881f877f27a66983a34d6869bf9663567e9 Signed-off-by: Narender Ankam --- drivers/video/fbdev/msm/mdss_hdmi_edid.c | 128 +++++++++++++++++++++++++++++++ drivers/video/fbdev/msm/mdss_hdmi_edid.h | 2 + drivers/video/fbdev/msm/mdss_hdmi_tx.c | 5 ++ 3 files changed, 135 insertions(+) diff --git a/drivers/video/fbdev/msm/mdss_hdmi_edid.c b/drivers/video/fbdev/msm/mdss_hdmi_edid.c index 6f0234500d70..5095f4ae49b5 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_edid.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_edid.c @@ -65,6 +65,11 @@ #define EDID_VENDOR_ID_SIZE 4 #define EDID_IEEE_REG_ID 0x0c03 +enum edid_screen_orientation { + LANDSCAPE = 1, + PORTRAIT = 2, +}; + enum edid_sink_mode { SINK_MODE_DVI, SINK_MODE_HDMI @@ -143,6 +148,8 @@ struct hdmi_edid_ctrl { u8 cea_blks; /* DC: MSB -> LSB: Y420_48|Y420_36|Y420_30|RGB48|RGB36|RGB30|Y444 */ u8 deep_color; + u8 physical_width; + u8 physical_height; u16 physical_address; u32 video_resolution; /* selected by user */ u32 sink_mode; /* HDMI or DVI */ @@ -167,6 +174,9 @@ struct hdmi_edid_ctrl { bool y420_cmdb_supports_all; struct hdmi_edid_y420_cmdb y420_cmdb; + enum edid_screen_orientation orientation; + enum aspect_ratio aspect_ratio; + struct hdmi_edid_sink_data sink_data; struct hdmi_edid_init_data init_data; struct hdmi_edid_sink_caps sink_caps; @@ -254,6 +264,11 @@ int hdmi_edid_reset_parser(void *input) edid_ctrl->y420_cmdb_supports_all = false; kfree(edid_ctrl->y420_cmdb.vic_list); memset(&edid_ctrl->y420_cmdb, 0, sizeof(edid_ctrl->y420_cmdb)); + + edid_ctrl->physical_width = 0; + edid_ctrl->physical_height = 0; + edid_ctrl->orientation = 0; + edid_ctrl->aspect_ratio = HDMI_RES_AR_INVALID; return 0; } @@ -449,6 +464,30 @@ static ssize_t hdmi_edid_sysfs_rda_modes(struct device *dev, static DEVICE_ATTR(edid_modes, S_IRUGO | S_IWUSR, hdmi_edid_sysfs_rda_modes, hdmi_edid_sysfs_wta_modes); +static ssize_t hdmi_edid_sysfs_rda_screen_size(struct device *dev, + struct device_attribute *attr, char *buf) +{ + ssize_t ret = 0; + struct hdmi_edid_ctrl *edid_ctrl = hdmi_edid_get_ctrl(dev); + + if (!edid_ctrl) { + DEV_ERR("%s: invalid input\n", __func__); + return -EINVAL; + } + + ret += scnprintf(buf + ret, PAGE_SIZE - ret, "%d", + (edid_ctrl->physical_width * 10)); + ret += scnprintf(buf + ret, PAGE_SIZE - ret, " %d", + (edid_ctrl->physical_height * 10)); + + DEV_DBG("%s: '%s'\n", __func__, buf); + ret += scnprintf(buf + ret, PAGE_SIZE - ret, "\n"); + + return ret; +} /* hdmi_edid_sysfs_rda_screen_size */ +static DEVICE_ATTR(edid_screen_size, S_IRUGO, hdmi_edid_sysfs_rda_screen_size, + NULL); + static ssize_t hdmi_edid_sysfs_rda_res_info_data(struct device *dev, struct device_attribute *attr, char *buf) { @@ -855,6 +894,7 @@ static DEVICE_ATTR(hdr_data, S_IRUGO, hdmi_edid_sysfs_rda_hdr_data, NULL); static struct attribute *hdmi_edid_fs_attrs[] = { &dev_attr_edid_modes.attr, + &dev_attr_edid_screen_size.attr, &dev_attr_pa.attr, &dev_attr_scan_info.attr, &dev_attr_edid_3d_modes.attr, @@ -1515,6 +1555,68 @@ static u32 hdmi_edid_extract_ieee_reg_id(struct hdmi_edid_ctrl *edid_ctrl, return ((u32)vsd[3] << 16) + ((u32)vsd[2] << 8) + (u32)vsd[1]; } /* hdmi_edid_extract_ieee_reg_id */ +static void hdmi_edid_extract_bdpf(struct hdmi_edid_ctrl *edid_ctrl) +{ + u8 *edid_buf = NULL; + + if (!edid_ctrl) { + DEV_ERR("%s: invalid input\n", __func__); + return; + } + + edid_buf = edid_ctrl->edid_buf; + if (edid_buf[21] && edid_buf[22]) { + edid_ctrl->physical_width = edid_buf[21]; + edid_ctrl->physical_height = edid_buf[22]; + + DEV_DBG("%s: EDID: Horizontal Screen Size = %d cm\n", + __func__, edid_ctrl->physical_width); + DEV_DBG("%s: EDID: Vertical Screen Size = %d cm\n", + __func__, edid_ctrl->physical_height); + } else if (edid_buf[21]) { + edid_ctrl->orientation = LANDSCAPE; + switch (edid_buf[21]) { + case 0x4F: + edid_ctrl->aspect_ratio = HDMI_RES_AR_16_9; + break; + case 0x3D: + edid_ctrl->aspect_ratio = HDMI_RES_AR_16_10; + break; + case 0x22: + edid_ctrl->aspect_ratio = HDMI_RES_AR_4_3; + break; + case 0x1A: + edid_ctrl->aspect_ratio = HDMI_RES_AR_5_4; + break; + } + DEV_DBG("%s: EDID: Landscape Aspect Ratio = %d\n", + __func__, edid_ctrl->aspect_ratio); + } else if (edid_buf[22]) { + edid_ctrl->orientation = PORTRAIT; + switch (edid_buf[22]) { + case 0x4F: + edid_ctrl->aspect_ratio = HDMI_RES_AR_16_9; + break; + case 0x3D: + edid_ctrl->aspect_ratio = HDMI_RES_AR_16_10; + break; + case 0x22: + edid_ctrl->aspect_ratio = HDMI_RES_AR_4_3; + break; + case 0x1A: + edid_ctrl->aspect_ratio = HDMI_RES_AR_5_4; + break; + } + DEV_DBG("%s: EDID: Portrait Aspect Ratio = %d\n", + __func__, edid_ctrl->aspect_ratio); + } else { + pr_debug("%s: Undefined Screen size/Aspect ratio\n", __func__); + edid_ctrl->orientation = 0; + edid_ctrl->physical_width = 0; + edid_ctrl->physical_height = 0; + } +} + static void hdmi_edid_extract_vendor_id(struct hdmi_edid_ctrl *edid_ctrl) { char *vendor_id; @@ -2462,6 +2564,8 @@ int hdmi_edid_parser(void *input) hdmi_edid_extract_vendor_id(edid_ctrl); + hdmi_edid_extract_bdpf(edid_ctrl); + /* EDID_CEA_EXTENSION_FLAG[0x7E] - CEC extension byte */ num_of_cea_blocks = edid_buf[EDID_BLOCK_SIZE - 2]; DEV_DBG("%s: No. of CEA/Extended EDID blocks is [%u]\n", __func__, @@ -2914,6 +3018,30 @@ bool hdmi_edid_is_audio_supported(void *input) return (edid_ctrl->basic_audio_supp || edid_ctrl->adb_size); } +u32 hdmi_edid_get_phys_width(void *input) +{ + struct hdmi_edid_ctrl *edid_ctrl = (struct hdmi_edid_ctrl *)input; + + if (!edid_ctrl) { + DEV_ERR("%s: invalid edid_ctrl data\n", __func__); + return 0; + } + + return (u32)edid_ctrl->physical_width * 10; /* return in mm */ +} + +u32 hdmi_edid_get_phys_height(void *input) +{ + struct hdmi_edid_ctrl *edid_ctrl = (struct hdmi_edid_ctrl *)input; + + if (!edid_ctrl) { + DEV_ERR("%s: invalid edid_ctrl data\n", __func__); + return 0; + } + + return (u32)edid_ctrl->physical_height * 10; /* return in mm */ +} + void hdmi_edid_deinit(void *input) { struct hdmi_edid_ctrl *edid_ctrl = (struct hdmi_edid_ctrl *)input; diff --git a/drivers/video/fbdev/msm/mdss_hdmi_edid.h b/drivers/video/fbdev/msm/mdss_hdmi_edid.h index d258aa9f95bc..9b3b5fa952b4 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_edid.h +++ b/drivers/video/fbdev/msm/mdss_hdmi_edid.h @@ -94,5 +94,7 @@ void hdmi_edid_set_max_pclk_rate(void *input, u32 max_pclk_khz); bool hdmi_edid_is_audio_supported(void *input); u32 hdmi_edid_get_sink_caps_max_tmds_clk(void *input); u8 hdmi_edid_get_colorimetry(void *input); +u32 hdmi_edid_get_phys_width(void *input); +u32 hdmi_edid_get_phys_height(void *input); #endif /* __HDMI_EDID_H__ */ diff --git a/drivers/video/fbdev/msm/mdss_hdmi_tx.c b/drivers/video/fbdev/msm/mdss_hdmi_tx.c index 747c245bf78e..8623a14df4ab 100644 --- a/drivers/video/fbdev/msm/mdss_hdmi_tx.c +++ b/drivers/video/fbdev/msm/mdss_hdmi_tx.c @@ -4125,6 +4125,7 @@ sysfs_err: static int hdmi_tx_evt_handle_check_param(struct hdmi_tx_ctrl *hdmi_ctrl) { struct mdss_panel_info *pinfo = &hdmi_ctrl->panel_data.panel_info; + void *data = NULL; int new_vic = -1; int rc = 0; @@ -4136,6 +4137,10 @@ static int hdmi_tx_evt_handle_check_param(struct hdmi_tx_ctrl *hdmi_ctrl) goto end; } + data = hdmi_tx_get_fd(HDMI_TX_FEAT_EDID); + pinfo->physical_width = hdmi_edid_get_phys_width(data); + pinfo->physical_height = hdmi_edid_get_phys_height(data); + /* * return value of 1 lets mdss know that panel * needs a reconfig due to new resolution and -- cgit v1.2.3 From 9e9985daafd996988fa802a6e6ede91cb77fcf81 Mon Sep 17 00:00:00 2001 From: Shashi Kant Maurya Date: Sun, 1 Nov 2020 22:09:03 +0530 Subject: RM: dts: msm: add CPU dai for additional proxy ports add CPU dai proxy ports 8194 and 8195 required for Call Screening. Change-Id: If38b4d61aed06edbe8b98c8e98effbe1d4810e0c Signed-off-by: Shashi Kant Maurya --- arch/arm/boot/dts/qcom/msm-audio-lpass.dtsi | 12 +++++++++++- arch/arm/boot/dts/qcom/msm8998-audio.dtsi | 14 +++++++++----- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/arch/arm/boot/dts/qcom/msm-audio-lpass.dtsi b/arch/arm/boot/dts/qcom/msm-audio-lpass.dtsi index aef9200f5d22..51c4c8c5be22 100644 --- a/arch/arm/boot/dts/qcom/msm-audio-lpass.dtsi +++ b/arch/arm/boot/dts/qcom/msm-audio-lpass.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, 2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2017, 2019-2020 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 @@ -293,6 +293,16 @@ qcom,msm-dai-q6-dev-id = <32770>; }; + proxy_rx: qcom,msm-dai-q6-proxy-rx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <8194>; + }; + + proxy_tx: qcom,msm-dai-q6-proxy-tx { + compatible = "qcom,msm-dai-q6-dev"; + qcom,msm-dai-q6-dev-id = <8195>; + }; + usb_audio_rx: qcom,msm-dai-q6-usb-audio-rx { compatible = "qcom,msm-dai-q6-dev"; qcom,msm-dai-q6-dev-id = <28672>; diff --git a/arch/arm/boot/dts/qcom/msm8998-audio.dtsi b/arch/arm/boot/dts/qcom/msm8998-audio.dtsi index 2e37ff6fe953..0481f8a6941c 100644 --- a/arch/arm/boot/dts/qcom/msm8998-audio.dtsi +++ b/arch/arm/boot/dts/qcom/msm8998-audio.dtsi @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, 2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2017, 2019-2020 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 @@ -122,7 +122,8 @@ <&dai_pri_tdm_rx_0>, <&dai_pri_tdm_tx_0>, <&dai_sec_tdm_rx_0>, <&dai_sec_tdm_tx_0>, <&dai_tert_tdm_rx_0>, <&dai_tert_tdm_tx_0>, - <&dai_quat_tdm_rx_0>, <&dai_quat_tdm_tx_0>; + <&dai_quat_tdm_rx_0>, <&dai_quat_tdm_tx_0>, + <&proxy_rx>, <&proxy_tx>; asoc-cpu-names = "msm-dai-q6-hdmi.8", "msm-dai-q6-dp.24608", "msm-dai-q6-mi2s.0", "msm-dai-q6-mi2s.1", "msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3", @@ -144,7 +145,8 @@ "msm-dai-q6-tdm.36864", "msm-dai-q6-tdm.36865", "msm-dai-q6-tdm.36880", "msm-dai-q6-tdm.36881", "msm-dai-q6-tdm.36896", "msm-dai-q6-tdm.36897", - "msm-dai-q6-tdm.36912", "msm-dai-q6-tdm.36913"; + "msm-dai-q6-tdm.36912", "msm-dai-q6-tdm.36913", + "msm-dai-q6-dev.8194", "msm-dai-q6-dev.8195"; asoc-codec = <&stub_codec>, <&ext_disp_audio_codec>; asoc-codec-names = "msm-stub-codec.1", "msm-ext-disp-audio-codec-rx"; @@ -255,7 +257,8 @@ <&dai_pri_tdm_rx_0>, <&dai_pri_tdm_tx_0>, <&dai_sec_tdm_rx_0>, <&dai_sec_tdm_tx_0>, <&dai_tert_tdm_rx_0>, <&dai_tert_tdm_tx_0>, - <&dai_quat_tdm_rx_0>, <&dai_quat_tdm_tx_0>; + <&dai_quat_tdm_rx_0>, <&dai_quat_tdm_tx_0>, + <&proxy_rx>, <&proxy_tx>; asoc-cpu-names = "msm-dai-q6-hdmi.8", "msm-dai-q6-dp.24608", "msm-dai-q6-mi2s.0", "msm-dai-q6-mi2s.1", "msm-dai-q6-mi2s.2", "msm-dai-q6-mi2s.3", @@ -277,7 +280,8 @@ "msm-dai-q6-tdm.36864", "msm-dai-q6-tdm.36865", "msm-dai-q6-tdm.36880", "msm-dai-q6-tdm.36881", "msm-dai-q6-tdm.36896", "msm-dai-q6-tdm.36897", - "msm-dai-q6-tdm.36912", "msm-dai-q6-tdm.36913"; + "msm-dai-q6-tdm.36912", "msm-dai-q6-tdm.36913", + "msm-dai-q6-dev.8194", "msm-dai-q6-dev.8195"; asoc-codec = <&stub_codec>, <&ext_disp_audio_codec>; asoc-codec-names = "msm-stub-codec.1", "msm-ext-disp-audio-codec-rx"; -- cgit v1.2.3 From 20e0355f8709fb83f7f0d194355fe09283b25ad7 Mon Sep 17 00:00:00 2001 From: Swetha Chikkaboraiah Date: Wed, 18 Nov 2020 11:55:09 +0530 Subject: defconfig: Enable CONFIG_UTS_NS for msm8998 Enable CONFIG_UTS_NS for complaince with CTS suite for msm8998. Change-Id: I8afcc88d72eaf08acc788115a5b05f655d062124 Signed-off-by: Swetha Chikkaboraiah --- arch/arm64/configs/msmcortex-perf_defconfig | 1 - arch/arm64/configs/msmcortex_defconfig | 1 - 2 files changed, 2 deletions(-) diff --git a/arch/arm64/configs/msmcortex-perf_defconfig b/arch/arm64/configs/msmcortex-perf_defconfig index 6e3cbeff1576..99851afe2188 100644 --- a/arch/arm64/configs/msmcortex-perf_defconfig +++ b/arch/arm64/configs/msmcortex-perf_defconfig @@ -26,7 +26,6 @@ CONFIG_SCHED_HMP=y CONFIG_SCHED_HMP_CSTATE_AWARE=y CONFIG_SCHED_CORE_CTL=y CONFIG_NAMESPACES=y -# CONFIG_UTS_NS is not set # CONFIG_PID_NS is not set CONFIG_SCHED_AUTOGROUP=y CONFIG_SCHED_TUNE=y diff --git a/arch/arm64/configs/msmcortex_defconfig b/arch/arm64/configs/msmcortex_defconfig index 51d31bc72348..38d18b69d67a 100644 --- a/arch/arm64/configs/msmcortex_defconfig +++ b/arch/arm64/configs/msmcortex_defconfig @@ -25,7 +25,6 @@ CONFIG_SCHED_HMP=y CONFIG_SCHED_HMP_CSTATE_AWARE=y CONFIG_SCHED_CORE_CTL=y CONFIG_NAMESPACES=y -# CONFIG_UTS_NS is not set # CONFIG_PID_NS is not set CONFIG_SCHED_AUTOGROUP=y CONFIG_SCHED_TUNE=y -- cgit v1.2.3 From 9cbb5c81008f2c0edb8b1596fcd39ae652b9b972 Mon Sep 17 00:00:00 2001 From: Swetha Chikkaboraiah Date: Fri, 25 Sep 2020 11:58:16 +0530 Subject: ARM: dts: msm: Enable vibrator in sdm660 DT support to enable vibrator in sdm660 Change-Id: Ifa81ea61600ce6c5850a21db60664351d49642e7 Signed-off-by: Swetha Chikkaboraiah --- arch/arm/boot/dts/qcom/msm-pm660.dtsi | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/arch/arm/boot/dts/qcom/msm-pm660.dtsi b/arch/arm/boot/dts/qcom/msm-pm660.dtsi index 460e7e76ac4d..2082934112a0 100644 --- a/arch/arm/boot/dts/qcom/msm-pm660.dtsi +++ b/arch/arm/boot/dts/qcom/msm-pm660.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, 2020, 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 @@ -629,29 +629,25 @@ #address-cells = <2>; #size-cells = <0>; - pm660_haptics: qcom,haptic@c000 { - compatible = "qcom,qpnp-haptic"; + pm660_haptics: qcom,haptics@c000 { + compatible = "qcom,qpnp-haptics"; reg = <0xc000 0x100>; interrupts = <0x1 0xc0 0x0 IRQ_TYPE_EDGE_BOTH>, - <0x1 0xc0 0x1 IRQ_TYPE_EDGE_BOTH>; - interrupt-names = "sc-irq", "play-irq"; + <0x1 0xc0 0x1 IRQ_TYPE_EDGE_BOTH>; + interrupt-names = "hap-sc-irq", "hap-play-irq"; qcom,pmic-revid = <&pm660_revid>; qcom,pmic-misc = <&pm660_misc>; qcom,misc-clk-trim-error-reg = <0xf3>; - qcom,actuator-type = "lra"; + qcom,actuator-type = <0>; qcom,play-mode = "direct"; qcom,vmax-mv = <3200>; qcom,ilim-ma = <800>; - qcom,wave-shape = "square"; + qcom,sc-dbc-cycles = <8>; qcom,wave-play-rate-us = <6667>; - qcom,int-pwm-freq-khz = <505>; - qcom,sc-deb-cycles = <8>; qcom,en-brake; - qcom,brake-pattern = [03 03 00 00]; qcom,lra-high-z = "opt0"; qcom,lra-auto-res-mode = "qwd"; - qcom,lra-calibrate-at-eop = <0>; - qcom,correct-lra-drive-freq; + qcom,lra-res-cal-period = <4>; }; }; }; -- cgit v1.2.3 From 2f192d556518300b260cebe2db15be3c0bc4ce0c Mon Sep 17 00:00:00 2001 From: Swetha Chikkaboraiah Date: Fri, 25 Sep 2020 12:06:41 +0530 Subject: defconfig: sdm660: enable LEDS_QPNP_HAPTICS Adding support LEDS_QPNP_HAPTICS driver for sdm660. Change-Id: Iabb8992de71021e22eac965a4d63f5a8c840f497 Signed-off-by: Swetha Chikkaboraiah --- arch/arm64/configs/sdm660_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/sdm660_defconfig b/arch/arm64/configs/sdm660_defconfig index 8df86944dce9..c43d03d477bb 100644 --- a/arch/arm64/configs/sdm660_defconfig +++ b/arch/arm64/configs/sdm660_defconfig @@ -513,6 +513,7 @@ CONFIG_LEDS_QPNP=y CONFIG_LEDS_QPNP_FLASH_V2=y CONFIG_LEDS_QPNP_WLED=y CONFIG_LEDS_SYSCON=y +CONFIG_LEDS_QPNP_HAPTICS=y CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_LEDS_TRIGGER_CPU=y -- cgit v1.2.3 From eeec266a93b5f36dbb635e89df4311acb4b03a03 Mon Sep 17 00:00:00 2001 From: Swetha Chikkaboraiah Date: Thu, 19 Nov 2020 17:14:43 +0530 Subject: defconfig: Enable CONFIG_HID_NINTENDO for msm8998 Enable CONFIG_HID_NINTENDO for msm8998. Change-Id: Ie9dfe6e48b4fce358f7d19f2f69a62eb37e2dd74 Signed-off-by: Swetha Chikkaboraiah --- arch/arm64/configs/msmcortex-perf_defconfig | 1 + arch/arm64/configs/msmcortex_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/configs/msmcortex-perf_defconfig b/arch/arm64/configs/msmcortex-perf_defconfig index 99851afe2188..c98953b95f9f 100644 --- a/arch/arm64/configs/msmcortex-perf_defconfig +++ b/arch/arm64/configs/msmcortex-perf_defconfig @@ -449,6 +449,7 @@ CONFIG_HID_ELECOM=y CONFIG_HID_MAGICMOUSE=y CONFIG_HID_MICROSOFT=y CONFIG_HID_MULTITOUCH=y +CONFIG_HID_NINTENDO=y CONFIG_HID_PLANTRONICS=y CONFIG_HID_SONY=y CONFIG_USB=y diff --git a/arch/arm64/configs/msmcortex_defconfig b/arch/arm64/configs/msmcortex_defconfig index 38d18b69d67a..81e70f0e42e0 100644 --- a/arch/arm64/configs/msmcortex_defconfig +++ b/arch/arm64/configs/msmcortex_defconfig @@ -456,6 +456,7 @@ CONFIG_HID_ELECOM=y CONFIG_HID_MAGICMOUSE=y CONFIG_HID_MICROSOFT=y CONFIG_HID_MULTITOUCH=y +CONFIG_HID_NINTENDO=y CONFIG_HID_PLANTRONICS=y CONFIG_HID_SONY=y CONFIG_USB=y -- cgit v1.2.3 From 254f50d07d80fd886e59404d6af71d837aac15d6 Mon Sep 17 00:00:00 2001 From: Jeff Vander Stoep Date: Wed, 22 Jan 2020 11:19:58 +0100 Subject: ANDROID: selinux: modify RTM_GETLINK permission Map the permission gating RTM_GETLINK messages to a new permission so that it can be distinguished from the other netlink route permissions in selinux policy. This is a temporary Android-only patch that will be deprecated in newer kernels once the long-term solution lands as discusssed on the mailing list [1]. The maintainer's recommended solution is more general, much more complex, and likely not suitable for backporting. This patch provides the minimal change needed for Android including the userspace settable trigger which ensures that the permission change is only applied to the newest version of Android which contains the changes needed for userpace compatibility. [1]: https://lore.kernel.org/selinux/20200116142653.61738-1-jeffv@google.com/ Bug: 141455849 Bug: 148218425 Test: CtsSelinuxTargetSdkCurrentTestCases Test: atest bionic-unit-tests-static Test: atest NetworkInterfaceTest Test: Connect to Wi-Fi network Test: Set up hotspot Test: Cast from device Test: Pair Bluetooth device Test: Call getifaddrs() directly from within an app. Test: Call NetworkInterface#getNetworkInterfaces() from within an app. Change-Id: I7b44ce60ad98f858c412722d41b9842f8577151f Signed-off-by: Jeff Vander Stoep Git-repo: https://android.googlesource.com/kernel/common Git-commit: ba835f8db4a3005e34542a3af7f19fce30ade6fd Signed-off-by: Alam Md Danish Signed-off-by: Swetha Chikkaboraiah --- security/selinux/include/classmap.h | 2 +- security/selinux/include/security.h | 2 ++ security/selinux/nlmsgtab.c | 24 ++++++++++++++++++++++++ security/selinux/ss/policydb.c | 4 ++++ security/selinux/ss/policydb.h | 2 ++ security/selinux/ss/services.c | 3 +++ 6 files changed, 36 insertions(+), 1 deletion(-) diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h index d40631150045..8a764f40730b 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h @@ -100,7 +100,7 @@ struct security_class_mapping secclass_map[] = { { COMMON_IPC_PERMS, NULL } }, { "netlink_route_socket", { COMMON_SOCK_PERMS, - "nlmsg_read", "nlmsg_write", NULL } }, + "nlmsg_read", "nlmsg_write", "nlmsg_readpriv", NULL } }, { "netlink_tcpdiag_socket", { COMMON_SOCK_PERMS, "nlmsg_read", "nlmsg_write", NULL } }, diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 0464cbb709cd..b45a3a72c161 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -78,6 +78,7 @@ enum { }; #define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1) +extern int selinux_android_netlink_route; extern int selinux_policycap_netpeer; extern int selinux_policycap_openperm; extern int selinux_policycap_alwaysnetwork; @@ -263,6 +264,7 @@ extern struct vfsmount *selinuxfs_mount; extern void selnl_notify_setenforce(int val); extern void selnl_notify_policyload(u32 seqno); extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm); +extern void selinux_nlmsg_init(void); #endif /* _SELINUX_SECURITY_H_ */ diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c index 0714b4c61a8b..78a8c420b1f5 100644 --- a/security/selinux/nlmsgtab.c +++ b/security/selinux/nlmsgtab.c @@ -191,3 +191,27 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm) return err; } + +static void nlmsg_set_getlink_perm(u32 perm) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(nlmsg_route_perms); i++) { + if (nlmsg_route_perms[i].nlmsg_type == RTM_GETLINK) { + nlmsg_route_perms[i].perm = perm; + break; + } + } +} + +/** + * Use nlmsg_readpriv as the permission for RTM_GETLINK messages if the + * netlink_route_getlink policy capability is set. Otherwise use nlmsg_read. + */ +void selinux_nlmsg_init(void) +{ + if (selinux_android_netlink_route) + nlmsg_set_getlink_perm(NETLINK_ROUTE_SOCKET__NLMSG_READPRIV); + else + nlmsg_set_getlink_perm(NETLINK_ROUTE_SOCKET__NLMSG_READ); +} diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index 01fbbbf89f41..5ee23e3a3678 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c @@ -2329,6 +2329,10 @@ int policydb_read(struct policydb *p, void *fp) p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN); p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN); + if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_ANDROID_NETLINK_ROUTE)) { + p->android_netlink_route = 1; + } + if (p->policyvers >= POLICYDB_VERSION_POLCAP) { rc = ebitmap_read(&p->policycaps, fp); if (rc) diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h index 725d5945a97e..0d511cf3c1e9 100644 --- a/security/selinux/ss/policydb.h +++ b/security/selinux/ss/policydb.h @@ -227,6 +227,7 @@ struct genfs { /* The policy database */ struct policydb { int mls_enabled; + int android_netlink_route; /* symbol tables */ struct symtab symtab[SYM_NUM]; @@ -313,6 +314,7 @@ extern int policydb_write(struct policydb *p, void *fp); #define PERM_SYMTAB_SIZE 32 #define POLICYDB_CONFIG_MLS 1 +#define POLICYDB_CONFIG_ANDROID_NETLINK_ROUTE (1 << 31) /* the config flags related to unknown classes/perms are bits 2 and 3 */ #define REJECT_UNKNOWN 0x00000002 diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 0a258c0602d1..5a6df05271a1 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -70,6 +70,7 @@ #include "ebitmap.h" #include "audit.h" +int selinux_android_netlink_route; int selinux_policycap_netpeer; int selinux_policycap_openperm; int selinux_policycap_alwaysnetwork; @@ -1997,6 +1998,8 @@ static void security_load_policycaps(void) POLICYDB_CAPABILITY_OPENPERM); selinux_policycap_alwaysnetwork = ebitmap_get_bit(&policydb.policycaps, POLICYDB_CAPABILITY_ALWAYSNETWORK); + selinux_android_netlink_route = policydb.android_netlink_route; + selinux_nlmsg_init(); } static int security_preserve_bools(struct policydb *p); -- cgit v1.2.3 From 6f09f538e14ea51f798f6a1709b04ddfa03d253b Mon Sep 17 00:00:00 2001 From: Swetha Chikkaboraiah Date: Fri, 4 Dec 2020 17:45:19 +0530 Subject: defconfig: Enable UTS_NS for sdm660 Enable CONFIG_UTS_NS for sdm660. Change-Id: Ib40d7bd614890e6b0a1564d5b82a28ce66b2bad4 Signed-off-by: Swetha Chikkaboraiah --- arch/arm64/configs/sdm660-perf_defconfig | 1 - arch/arm64/configs/sdm660_defconfig | 1 - 2 files changed, 2 deletions(-) diff --git a/arch/arm64/configs/sdm660-perf_defconfig b/arch/arm64/configs/sdm660-perf_defconfig index 274519f7055a..ba31684a574f 100644 --- a/arch/arm64/configs/sdm660-perf_defconfig +++ b/arch/arm64/configs/sdm660-perf_defconfig @@ -26,7 +26,6 @@ CONFIG_SCHED_HMP=y CONFIG_SCHED_HMP_CSTATE_AWARE=y CONFIG_SCHED_CORE_CTL=y CONFIG_NAMESPACES=y -# CONFIG_UTS_NS is not set # CONFIG_PID_NS is not set CONFIG_SCHED_AUTOGROUP=y CONFIG_SCHED_TUNE=y diff --git a/arch/arm64/configs/sdm660_defconfig b/arch/arm64/configs/sdm660_defconfig index c43d03d477bb..0478840268fc 100644 --- a/arch/arm64/configs/sdm660_defconfig +++ b/arch/arm64/configs/sdm660_defconfig @@ -25,7 +25,6 @@ CONFIG_SCHED_HMP=y CONFIG_SCHED_HMP_CSTATE_AWARE=y CONFIG_SCHED_CORE_CTL=y CONFIG_NAMESPACES=y -# CONFIG_UTS_NS is not set # CONFIG_PID_NS is not set CONFIG_SCHED_AUTOGROUP=y CONFIG_SCHED_TUNE=y -- cgit v1.2.3 From 4692d4bc60295c4f967f15dc1136f5d5a0d01476 Mon Sep 17 00:00:00 2001 From: "Daniel J. Ogorchock" Date: Sun, 29 Dec 2019 19:27:09 -0600 Subject: FROMLIST: HID: nintendo: add nintendo switch controller driver The hid-nintendo driver supports the Nintendo Switch Pro Controllers and the Joy-Cons. The Pro Controllers can be used over USB or Bluetooth. The Joy-Cons each create their own, independent input devices, so it is up to userspace to combine them if desired. Signed-off-by: Daniel J. Ogorchock Test: tested via custom test app Test: atest NintendoSwitchProTest. Bug: 135136477 Link: https://patchwork.kernel.org/patch/11312547/ Link: https://lore.kernel.org/linux-input/20191230012720.2368987-2-djogorchock@gmail.com/ Change-Id: I179da1092faedc2ad25336224cf5ec8ff00e0d3f Signed-off-by: Siarhei Vishniakou Git-commit: b05c992acd41b01629d2035d54ef6d4ed6334e0f Git-repo: https://android.googlesource.com/kernel/common Signed-off-by: Srinivasarao P Signed-off-by: Swetha Chikkaboraiah --- MAINTAINERS | 6 + drivers/hid/Kconfig | 11 + drivers/hid/Makefile | 1 + drivers/hid/hid-core.c | 10 + drivers/hid/hid-ids.h | 3 + drivers/hid/hid-nintendo.c | 820 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 851 insertions(+) create mode 100644 drivers/hid/hid-nintendo.c diff --git a/MAINTAINERS b/MAINTAINERS index c927bdcef19b..293aca692855 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7611,6 +7611,12 @@ S: Maintained F: Documentation/scsi/NinjaSCSI.txt F: drivers/scsi/nsp32* +NINTENDO HID DRIVER +M: Daniel J. Ogorchock +L: linux-input@vger.kernel.org +S: Maintained +F: drivers/hid/hid-nintendo* + NIOS2 ARCHITECTURE M: Ley Foon Tan L: nios2-dev@lists.rocketboards.org (moderated for non-subscribers) diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 1107d218b0c5..86cafbb16308 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -536,6 +536,17 @@ config HID_MULTITOUCH To compile this driver as a module, choose M here: the module will be called hid-multitouch. +config HID_NINTENDO + tristate "Nintendo Joy-Con and Pro Controller support" + depends on HID + help + Adds support for the Nintendo Switch Joy-Cons and Pro Controller. + All controllers support bluetooth, and the Pro Controller also supports + its USB mode. + + To compile this driver as a module, choose M here: the + module will be called hid-nintendo. + config HID_NTRIG tristate "N-Trig touch screen" depends on USB_HID diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index c21ff739fb31..892b5fe6dfc8 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -58,6 +58,7 @@ obj-$(CONFIG_HID_MAGICMOUSE) += hid-magicmouse.o obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o obj-$(CONFIG_HID_MULTITOUCH) += hid-multitouch.o +obj-$(CONFIG_HID_NINTENDO) += hid-nintendo.o obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o obj-$(CONFIG_HID_ORTEK) += hid-ortek.o obj-$(CONFIG_HID_PRODIKEYS) += hid-prodikeys.o diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index f6476d1cfdb2..b8cca99f36e6 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2022,6 +2022,16 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_RYOS_MK_PRO) }, { HID_USB_DEVICE(USB_VENDOR_ID_ROCCAT, USB_DEVICE_ID_ROCCAT_SAVU) }, #endif +#if IS_ENABLED(CONFIG_HID_NINTENDO) + { HID_USB_DEVICE(USB_VENDOR_ID_NINTENDO, + USB_DEVICE_ID_NINTENDO_PROCON) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, + USB_DEVICE_ID_NINTENDO_PROCON) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, + USB_DEVICE_ID_NINTENDO_JOYCONL) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, + USB_DEVICE_ID_NINTENDO_JOYCONR) }, +#endif #if IS_ENABLED(CONFIG_HID_SAITEK) { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_PS1000) }, { HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7_OLD) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index b4bc316310bc..020a4bfa2629 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -731,6 +731,9 @@ #define USB_VENDOR_ID_NINTENDO 0x057e #define USB_DEVICE_ID_NINTENDO_WIIMOTE 0x0306 #define USB_DEVICE_ID_NINTENDO_WIIMOTE2 0x0330 +#define USB_DEVICE_ID_NINTENDO_JOYCONL 0x2006 +#define USB_DEVICE_ID_NINTENDO_JOYCONR 0x2007 +#define USB_DEVICE_ID_NINTENDO_PROCON 0x2009 #define USB_VENDOR_ID_NOVATEK 0x0603 #define USB_DEVICE_ID_NOVATEK_PCT 0x0600 diff --git a/drivers/hid/hid-nintendo.c b/drivers/hid/hid-nintendo.c new file mode 100644 index 000000000000..3695b96694bd --- /dev/null +++ b/drivers/hid/hid-nintendo.c @@ -0,0 +1,820 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * HID driver for Nintendo Switch Joy-Cons and Pro Controllers + * + * Copyright (c) 2019 Daniel J. Ogorchock + * + * The following resources/projects were referenced for this driver: + * https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering + * https://gitlab.com/pjranki/joycon-linux-kernel (Peter Rankin) + * https://github.com/FrotBot/SwitchProConLinuxUSB + * https://github.com/MTCKC/ProconXInput + * hid-wiimote kernel hid driver + * hid-logitech-hidpp driver + * + * This driver supports the Nintendo Switch Joy-Cons and Pro Controllers. The + * Pro Controllers can either be used over USB or Bluetooth. + * + * The driver will retrieve the factory calibration info from the controllers, + * so little to no user calibration should be required. + * + */ + +#include "hid-ids.h" +#include +#include +#include +#include +#include +#include + +/* + * Reference the url below for the following HID report defines: + * https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering + */ + +/* Output Reports */ +static const u8 JC_OUTPUT_RUMBLE_AND_SUBCMD = 0x01; +static const u8 JC_OUTPUT_FW_UPDATE_PKT = 0x03; +static const u8 JC_OUTPUT_RUMBLE_ONLY = 0x10; +static const u8 JC_OUTPUT_MCU_DATA = 0x11; +static const u8 JC_OUTPUT_USB_CMD = 0x80; + +/* Subcommand IDs */ +static const u8 JC_SUBCMD_STATE /*= 0x00*/; +static const u8 JC_SUBCMD_MANUAL_BT_PAIRING = 0x01; +static const u8 JC_SUBCMD_REQ_DEV_INFO = 0x02; +static const u8 JC_SUBCMD_SET_REPORT_MODE = 0x03; +static const u8 JC_SUBCMD_TRIGGERS_ELAPSED = 0x04; +static const u8 JC_SUBCMD_GET_PAGE_LIST_STATE = 0x05; +static const u8 JC_SUBCMD_SET_HCI_STATE = 0x06; +static const u8 JC_SUBCMD_RESET_PAIRING_INFO = 0x07; +static const u8 JC_SUBCMD_LOW_POWER_MODE = 0x08; +static const u8 JC_SUBCMD_SPI_FLASH_READ = 0x10; +static const u8 JC_SUBCMD_SPI_FLASH_WRITE = 0x11; +static const u8 JC_SUBCMD_RESET_MCU = 0x20; +static const u8 JC_SUBCMD_SET_MCU_CONFIG = 0x21; +static const u8 JC_SUBCMD_SET_MCU_STATE = 0x22; +static const u8 JC_SUBCMD_SET_PLAYER_LIGHTS = 0x30; +static const u8 JC_SUBCMD_GET_PLAYER_LIGHTS = 0x31; +static const u8 JC_SUBCMD_SET_HOME_LIGHT = 0x38; +static const u8 JC_SUBCMD_ENABLE_IMU = 0x40; +static const u8 JC_SUBCMD_SET_IMU_SENSITIVITY = 0x41; +static const u8 JC_SUBCMD_WRITE_IMU_REG = 0x42; +static const u8 JC_SUBCMD_READ_IMU_REG = 0x43; +static const u8 JC_SUBCMD_ENABLE_VIBRATION = 0x48; +static const u8 JC_SUBCMD_GET_REGULATED_VOLTAGE = 0x50; + +/* Input Reports */ +static const u8 JC_INPUT_BUTTON_EVENT = 0x3F; +static const u8 JC_INPUT_SUBCMD_REPLY = 0x21; +static const u8 JC_INPUT_IMU_DATA = 0x30; +static const u8 JC_INPUT_MCU_DATA = 0x31; +static const u8 JC_INPUT_USB_RESPONSE = 0x81; + +/* Feature Reports */ +static const u8 JC_FEATURE_LAST_SUBCMD = 0x02; +static const u8 JC_FEATURE_OTA_FW_UPGRADE = 0x70; +static const u8 JC_FEATURE_SETUP_MEM_READ = 0x71; +static const u8 JC_FEATURE_MEM_READ = 0x72; +static const u8 JC_FEATURE_ERASE_MEM_SECTOR = 0x73; +static const u8 JC_FEATURE_MEM_WRITE = 0x74; +static const u8 JC_FEATURE_LAUNCH = 0x75; + +/* USB Commands */ +static const u8 JC_USB_CMD_CONN_STATUS = 0x01; +static const u8 JC_USB_CMD_HANDSHAKE = 0x02; +static const u8 JC_USB_CMD_BAUDRATE_3M = 0x03; +static const u8 JC_USB_CMD_NO_TIMEOUT = 0x04; +static const u8 JC_USB_CMD_EN_TIMEOUT = 0x05; +static const u8 JC_USB_RESET = 0x06; +static const u8 JC_USB_PRE_HANDSHAKE = 0x91; +static const u8 JC_USB_SEND_UART = 0x92; + +/* SPI storage addresses of factory calibration data */ +static const u16 JC_CAL_DATA_START = 0x603d; +static const u16 JC_CAL_DATA_END = 0x604e; +#define JC_CAL_DATA_SIZE (JC_CAL_DATA_END - JC_CAL_DATA_START + 1) + + +/* The raw analog joystick values will be mapped in terms of this magnitude */ +static const u16 JC_MAX_STICK_MAG = 32767; +static const u16 JC_STICK_FUZZ = 250; +static const u16 JC_STICK_FLAT = 500; + +/* States for controller state machine */ +enum joycon_ctlr_state { + JOYCON_CTLR_STATE_INIT, + JOYCON_CTLR_STATE_READ, +}; + +struct joycon_stick_cal { + s32 max; + s32 min; + s32 center; +}; + +/* + * All the controller's button values are stored in a u32. + * They can be accessed with bitwise ANDs. + */ +static const u32 JC_BTN_Y = BIT(0); +static const u32 JC_BTN_X = BIT(1); +static const u32 JC_BTN_B = BIT(2); +static const u32 JC_BTN_A = BIT(3); +static const u32 JC_BTN_SR_R = BIT(4); +static const u32 JC_BTN_SL_R = BIT(5); +static const u32 JC_BTN_R = BIT(6); +static const u32 JC_BTN_ZR = BIT(7); +static const u32 JC_BTN_MINUS = BIT(8); +static const u32 JC_BTN_PLUS = BIT(9); +static const u32 JC_BTN_RSTICK = BIT(10); +static const u32 JC_BTN_LSTICK = BIT(11); +static const u32 JC_BTN_HOME = BIT(12); +static const u32 JC_BTN_CAP = BIT(13); /* capture button */ +static const u32 JC_BTN_DOWN = BIT(16); +static const u32 JC_BTN_UP = BIT(17); +static const u32 JC_BTN_RIGHT = BIT(18); +static const u32 JC_BTN_LEFT = BIT(19); +static const u32 JC_BTN_SR_L = BIT(20); +static const u32 JC_BTN_SL_L = BIT(21); +static const u32 JC_BTN_L = BIT(22); +static const u32 JC_BTN_ZL = BIT(23); + +enum joycon_msg_type { + JOYCON_MSG_TYPE_NONE, + JOYCON_MSG_TYPE_USB, + JOYCON_MSG_TYPE_SUBCMD, +}; + +struct joycon_subcmd_request { + u8 output_id; /* must be 0x01 for subcommand, 0x10 for rumble only */ + u8 packet_num; /* incremented every send */ + u8 rumble_data[8]; + u8 subcmd_id; + u8 data[0]; /* length depends on the subcommand */ +} __packed; + +struct joycon_subcmd_reply { + u8 ack; /* MSB 1 for ACK, 0 for NACK */ + u8 id; /* id of requested subcmd */ + u8 data[0]; /* will be at most 35 bytes */ +} __packed; + +struct joycon_input_report { + u8 id; + u8 timer; + u8 bat_con; /* battery and connection info */ + u8 button_status[3]; + u8 left_stick[3]; + u8 right_stick[3]; + u8 vibrator_report; + + /* + * If support for firmware updates, gyroscope data, and/or NFC/IR + * are added in the future, this can be swapped for a union. + */ + struct joycon_subcmd_reply reply; +} __packed; + +#define JC_MAX_RESP_SIZE (sizeof(struct joycon_input_report) + 35) + +/* Each physical controller is associated with a joycon_ctlr struct */ +struct joycon_ctlr { + struct hid_device *hdev; + struct input_dev *input; + enum joycon_ctlr_state ctlr_state; + + /* The following members are used for synchronous sends/receives */ + enum joycon_msg_type msg_type; + u8 subcmd_num; + struct mutex output_mutex; + u8 input_buf[JC_MAX_RESP_SIZE]; + wait_queue_head_t wait; + bool received_resp; + u8 usb_ack_match; + u8 subcmd_ack_match; + + /* factory calibration data */ + struct joycon_stick_cal left_stick_cal_x; + struct joycon_stick_cal left_stick_cal_y; + struct joycon_stick_cal right_stick_cal_x; + struct joycon_stick_cal right_stick_cal_y; + +}; + +static int __joycon_hid_send(struct hid_device *hdev, u8 *data, size_t len) +{ + u8 *buf; + int ret; + + buf = kmemdup(data, len, GFP_KERNEL); + if (!buf) + return -ENOMEM; + ret = hid_hw_output_report(hdev, buf, len); + kfree(buf); + if (ret < 0) + hid_dbg(hdev, "Failed to send output report ret=%d\n", ret); + return ret; +} + +static int joycon_hid_send_sync(struct joycon_ctlr *ctlr, u8 *data, size_t len) +{ + int ret; + + ret = __joycon_hid_send(ctlr->hdev, data, len); + if (ret < 0) { + memset(ctlr->input_buf, 0, JC_MAX_RESP_SIZE); + return ret; + } + + if (!wait_event_timeout(ctlr->wait, ctlr->received_resp, HZ)) { + hid_dbg(ctlr->hdev, "synchronous send/receive timed out\n"); + memset(ctlr->input_buf, 0, JC_MAX_RESP_SIZE); + return -ETIMEDOUT; + } + + ctlr->received_resp = false; + return 0; +} + +static int joycon_send_usb(struct joycon_ctlr *ctlr, u8 cmd) +{ + int ret; + u8 buf[2] = {JC_OUTPUT_USB_CMD}; + + buf[1] = cmd; + ctlr->usb_ack_match = cmd; + ctlr->msg_type = JOYCON_MSG_TYPE_USB; + ret = joycon_hid_send_sync(ctlr, buf, sizeof(buf)); + if (ret) + hid_dbg(ctlr->hdev, "send usb command failed; ret=%d\n", ret); + return ret; +} + +static int joycon_send_subcmd(struct joycon_ctlr *ctlr, + struct joycon_subcmd_request *subcmd, + size_t data_len) +{ + int ret; + + subcmd->output_id = JC_OUTPUT_RUMBLE_AND_SUBCMD; + subcmd->packet_num = ctlr->subcmd_num; + if (++ctlr->subcmd_num > 0xF) + ctlr->subcmd_num = 0; + ctlr->subcmd_ack_match = subcmd->subcmd_id; + ctlr->msg_type = JOYCON_MSG_TYPE_SUBCMD; + + ret = joycon_hid_send_sync(ctlr, (u8 *)subcmd, + sizeof(*subcmd) + data_len); + if (ret < 0) + hid_dbg(ctlr->hdev, "send subcommand failed; ret=%d\n", ret); + else + ret = 0; + return ret; +} + +/* Supply nibbles for flash and on. Ones correspond to active */ +static int joycon_set_player_leds(struct joycon_ctlr *ctlr, u8 flash, u8 on) +{ + struct joycon_subcmd_request *req; + u8 buffer[sizeof(*req) + 1] = { 0 }; + + req = (struct joycon_subcmd_request *)buffer; + req->subcmd_id = JC_SUBCMD_SET_PLAYER_LIGHTS; + req->data[0] = (flash << 4) | on; + + hid_dbg(ctlr->hdev, "setting player leds\n"); + return joycon_send_subcmd(ctlr, req, 1); +} + +static const u16 DFLT_STICK_CAL_CEN = 2000; +static const u16 DFLT_STICK_CAL_MAX = 3500; +static const u16 DFLT_STICK_CAL_MIN = 500; +static int joycon_request_calibration(struct joycon_ctlr *ctlr) +{ + struct joycon_subcmd_request *req; + u8 buffer[sizeof(*req) + 5] = { 0 }; + struct joycon_input_report *report; + struct joycon_stick_cal *cal_x; + struct joycon_stick_cal *cal_y; + s32 x_max_above; + s32 x_min_below; + s32 y_max_above; + s32 y_min_below; + u8 *data; + u8 *raw_cal; + int ret; + + req = (struct joycon_subcmd_request *)buffer; + req->subcmd_id = JC_SUBCMD_SPI_FLASH_READ; + data = req->data; + data[0] = 0xFF & JC_CAL_DATA_START; + data[1] = 0xFF & (JC_CAL_DATA_START >> 8); + data[2] = 0xFF & (JC_CAL_DATA_START >> 16); + data[3] = 0xFF & (JC_CAL_DATA_START >> 24); + data[4] = JC_CAL_DATA_SIZE; + + hid_dbg(ctlr->hdev, "requesting cal data\n"); + ret = joycon_send_subcmd(ctlr, req, 5); + if (ret) { + hid_warn(ctlr->hdev, + "Failed to read stick cal, using defaults; ret=%d\n", + ret); + + ctlr->left_stick_cal_x.center = DFLT_STICK_CAL_CEN; + ctlr->left_stick_cal_x.max = DFLT_STICK_CAL_MAX; + ctlr->left_stick_cal_x.min = DFLT_STICK_CAL_MIN; + + ctlr->left_stick_cal_y.center = DFLT_STICK_CAL_CEN; + ctlr->left_stick_cal_y.max = DFLT_STICK_CAL_MAX; + ctlr->left_stick_cal_y.min = DFLT_STICK_CAL_MIN; + + ctlr->right_stick_cal_x.center = DFLT_STICK_CAL_CEN; + ctlr->right_stick_cal_x.max = DFLT_STICK_CAL_MAX; + ctlr->right_stick_cal_x.min = DFLT_STICK_CAL_MIN; + + ctlr->right_stick_cal_y.center = DFLT_STICK_CAL_CEN; + ctlr->right_stick_cal_y.max = DFLT_STICK_CAL_MAX; + ctlr->right_stick_cal_y.min = DFLT_STICK_CAL_MIN; + + return ret; + } + + report = (struct joycon_input_report *)ctlr->input_buf; + raw_cal = &report->reply.data[5]; + + /* left stick calibration parsing */ + cal_x = &ctlr->left_stick_cal_x; + cal_y = &ctlr->left_stick_cal_y; + + x_max_above = hid_field_extract(ctlr->hdev, (raw_cal + 0), 0, 12); + y_max_above = hid_field_extract(ctlr->hdev, (raw_cal + 1), 4, 12); + cal_x->center = hid_field_extract(ctlr->hdev, (raw_cal + 3), 0, 12); + cal_y->center = hid_field_extract(ctlr->hdev, (raw_cal + 4), 4, 12); + x_min_below = hid_field_extract(ctlr->hdev, (raw_cal + 6), 0, 12); + y_min_below = hid_field_extract(ctlr->hdev, (raw_cal + 7), 4, 12); + cal_x->max = cal_x->center + x_max_above; + cal_x->min = cal_x->center - x_min_below; + cal_y->max = cal_y->center + y_max_above; + cal_y->min = cal_y->center - y_min_below; + + /* right stick calibration parsing */ + raw_cal += 9; + cal_x = &ctlr->right_stick_cal_x; + cal_y = &ctlr->right_stick_cal_y; + + cal_x->center = hid_field_extract(ctlr->hdev, (raw_cal + 0), 0, 12); + cal_y->center = hid_field_extract(ctlr->hdev, (raw_cal + 1), 4, 12); + x_min_below = hid_field_extract(ctlr->hdev, (raw_cal + 3), 0, 12); + y_min_below = hid_field_extract(ctlr->hdev, (raw_cal + 4), 4, 12); + x_max_above = hid_field_extract(ctlr->hdev, (raw_cal + 6), 0, 12); + y_max_above = hid_field_extract(ctlr->hdev, (raw_cal + 7), 4, 12); + cal_x->max = cal_x->center + x_max_above; + cal_x->min = cal_x->center - x_min_below; + cal_y->max = cal_y->center + y_max_above; + cal_y->min = cal_y->center - y_min_below; + + hid_dbg(ctlr->hdev, "calibration:\n" + "l_x_c=%d l_x_max=%d l_x_min=%d\n" + "l_y_c=%d l_y_max=%d l_y_min=%d\n" + "r_x_c=%d r_x_max=%d r_x_min=%d\n" + "r_y_c=%d r_y_max=%d r_y_min=%d\n", + ctlr->left_stick_cal_x.center, + ctlr->left_stick_cal_x.max, + ctlr->left_stick_cal_x.min, + ctlr->left_stick_cal_y.center, + ctlr->left_stick_cal_y.max, + ctlr->left_stick_cal_y.min, + ctlr->right_stick_cal_x.center, + ctlr->right_stick_cal_x.max, + ctlr->right_stick_cal_x.min, + ctlr->right_stick_cal_y.center, + ctlr->right_stick_cal_y.max, + ctlr->right_stick_cal_y.min); + + return 0; +} + +static int joycon_set_report_mode(struct joycon_ctlr *ctlr) +{ + struct joycon_subcmd_request *req; + u8 buffer[sizeof(*req) + 1] = { 0 }; + + req = (struct joycon_subcmd_request *)buffer; + req->subcmd_id = JC_SUBCMD_SET_REPORT_MODE; + req->data[0] = 0x30; /* standard, full report mode */ + + hid_dbg(ctlr->hdev, "setting controller report mode\n"); + return joycon_send_subcmd(ctlr, req, 1); +} + +static s32 joycon_map_stick_val(struct joycon_stick_cal *cal, s32 val) +{ + s32 center = cal->center; + s32 min = cal->min; + s32 max = cal->max; + s32 new_val; + + if (val > center) { + new_val = (val - center) * JC_MAX_STICK_MAG; + new_val /= (max - center); + } else { + new_val = (center - val) * -JC_MAX_STICK_MAG; + new_val /= (center - min); + } + new_val = clamp(new_val, (s32)-JC_MAX_STICK_MAG, (s32)JC_MAX_STICK_MAG); + return new_val; +} + +static void joycon_parse_report(struct joycon_ctlr *ctlr, + struct joycon_input_report *rep) +{ + struct input_dev *dev = ctlr->input; + u32 btns; + u32 id = ctlr->hdev->product; + + btns = hid_field_extract(ctlr->hdev, rep->button_status, 0, 24); + + if (id != USB_DEVICE_ID_NINTENDO_JOYCONR) { + u16 raw_x; + u16 raw_y; + s32 x; + s32 y; + + /* get raw stick values */ + raw_x = hid_field_extract(ctlr->hdev, rep->left_stick, 0, 12); + raw_y = hid_field_extract(ctlr->hdev, + rep->left_stick + 1, 4, 12); + /* map the stick values */ + x = joycon_map_stick_val(&ctlr->left_stick_cal_x, raw_x); + y = -joycon_map_stick_val(&ctlr->left_stick_cal_y, raw_y); + /* report sticks */ + input_report_abs(dev, ABS_X, x); + input_report_abs(dev, ABS_Y, y); + + /* report buttons */ + input_report_key(dev, BTN_TL, btns & JC_BTN_L); + input_report_key(dev, BTN_TL2, btns & JC_BTN_ZL); + if (id != USB_DEVICE_ID_NINTENDO_PROCON) { + /* Report the S buttons as the non-existent triggers */ + input_report_key(dev, BTN_TR, btns & JC_BTN_SL_L); + input_report_key(dev, BTN_TR2, btns & JC_BTN_SR_L); + } + input_report_key(dev, BTN_SELECT, btns & JC_BTN_MINUS); + input_report_key(dev, BTN_THUMBL, btns & JC_BTN_LSTICK); + input_report_key(dev, BTN_Z, btns & JC_BTN_CAP); + input_report_key(dev, BTN_DPAD_DOWN, btns & JC_BTN_DOWN); + input_report_key(dev, BTN_DPAD_UP, btns & JC_BTN_UP); + input_report_key(dev, BTN_DPAD_RIGHT, btns & JC_BTN_RIGHT); + input_report_key(dev, BTN_DPAD_LEFT, btns & JC_BTN_LEFT); + } + if (id != USB_DEVICE_ID_NINTENDO_JOYCONL) { + u16 raw_x; + u16 raw_y; + s32 x; + s32 y; + + /* get raw stick values */ + raw_x = hid_field_extract(ctlr->hdev, rep->right_stick, 0, 12); + raw_y = hid_field_extract(ctlr->hdev, + rep->right_stick + 1, 4, 12); + /* map stick values */ + x = joycon_map_stick_val(&ctlr->right_stick_cal_x, raw_x); + y = -joycon_map_stick_val(&ctlr->right_stick_cal_y, raw_y); + /* report sticks */ + input_report_abs(dev, ABS_RX, x); + input_report_abs(dev, ABS_RY, y); + + /* report buttons */ + input_report_key(dev, BTN_TR, btns & JC_BTN_R); + input_report_key(dev, BTN_TR2, btns & JC_BTN_ZR); + if (id != USB_DEVICE_ID_NINTENDO_PROCON) { + /* Report the S buttons as the non-existent triggers */ + input_report_key(dev, BTN_TL, btns & JC_BTN_SL_R); + input_report_key(dev, BTN_TL2, btns & JC_BTN_SR_R); + } + input_report_key(dev, BTN_START, btns & JC_BTN_PLUS); + input_report_key(dev, BTN_THUMBR, btns & JC_BTN_RSTICK); + input_report_key(dev, BTN_MODE, btns & JC_BTN_HOME); + input_report_key(dev, BTN_WEST, btns & JC_BTN_Y); + input_report_key(dev, BTN_NORTH, btns & JC_BTN_X); + input_report_key(dev, BTN_EAST, btns & JC_BTN_A); + input_report_key(dev, BTN_SOUTH, btns & JC_BTN_B); + } + + input_sync(dev); +} + + +static const unsigned int joycon_button_inputs_l[] = { + BTN_SELECT, BTN_Z, BTN_THUMBL, + BTN_DPAD_UP, BTN_DPAD_DOWN, BTN_DPAD_LEFT, BTN_DPAD_RIGHT, + BTN_TL, BTN_TL2, + 0 /* 0 signals end of array */ +}; + +static const unsigned int joycon_button_inputs_r[] = { + BTN_START, BTN_MODE, BTN_THUMBR, + BTN_SOUTH, BTN_EAST, BTN_NORTH, BTN_WEST, + BTN_TR, BTN_TR2, + 0 /* 0 signals end of array */ +}; + +static DEFINE_MUTEX(joycon_input_num_mutex); +static int joycon_input_create(struct joycon_ctlr *ctlr) +{ + struct hid_device *hdev; + static int input_num = 1; + const char *name; + int ret; + int i; + + hdev = ctlr->hdev; + + switch (hdev->product) { + case USB_DEVICE_ID_NINTENDO_PROCON: + name = "Nintendo Switch Pro Controller"; + break; + case USB_DEVICE_ID_NINTENDO_JOYCONL: + name = "Nintendo Switch Left Joy-Con"; + break; + case USB_DEVICE_ID_NINTENDO_JOYCONR: + name = "Nintendo Switch Right Joy-Con"; + break; + default: /* Should be impossible */ + hid_err(hdev, "Invalid hid product\n"); + return -EINVAL; + } + + ctlr->input = devm_input_allocate_device(&hdev->dev); + if (!ctlr->input) + return -ENOMEM; + ctlr->input->id.bustype = hdev->bus; + ctlr->input->id.vendor = hdev->vendor; + ctlr->input->id.product = hdev->product; + ctlr->input->id.version = hdev->version; + ctlr->input->name = name; + input_set_drvdata(ctlr->input, ctlr); + + + /* set up sticks */ + if (hdev->product != USB_DEVICE_ID_NINTENDO_JOYCONR) { + input_set_abs_params(ctlr->input, ABS_X, + -JC_MAX_STICK_MAG, JC_MAX_STICK_MAG, + JC_STICK_FUZZ, JC_STICK_FLAT); + input_set_abs_params(ctlr->input, ABS_Y, + -JC_MAX_STICK_MAG, JC_MAX_STICK_MAG, + JC_STICK_FUZZ, JC_STICK_FLAT); + } + if (hdev->product != USB_DEVICE_ID_NINTENDO_JOYCONL) { + input_set_abs_params(ctlr->input, ABS_RX, + -JC_MAX_STICK_MAG, JC_MAX_STICK_MAG, + JC_STICK_FUZZ, JC_STICK_FLAT); + input_set_abs_params(ctlr->input, ABS_RY, + -JC_MAX_STICK_MAG, JC_MAX_STICK_MAG, + JC_STICK_FUZZ, JC_STICK_FLAT); + } + + /* set up buttons */ + if (hdev->product != USB_DEVICE_ID_NINTENDO_JOYCONR) { + for (i = 0; joycon_button_inputs_l[i] > 0; i++) + input_set_capability(ctlr->input, EV_KEY, + joycon_button_inputs_l[i]); + } + if (hdev->product != USB_DEVICE_ID_NINTENDO_JOYCONL) { + for (i = 0; joycon_button_inputs_r[i] > 0; i++) + input_set_capability(ctlr->input, EV_KEY, + joycon_button_inputs_r[i]); + } + + ret = input_register_device(ctlr->input); + if (ret) + return ret; + + /* Set the default controller player leds based on controller number */ + mutex_lock(&joycon_input_num_mutex); + mutex_lock(&ctlr->output_mutex); + ret = joycon_set_player_leds(ctlr, 0, 0xF >> (4 - input_num)); + if (ret) + hid_warn(ctlr->hdev, "Failed to set leds; ret=%d\n", ret); + mutex_unlock(&ctlr->output_mutex); + if (++input_num > 4) + input_num = 1; + mutex_unlock(&joycon_input_num_mutex); + + return 0; +} + +/* Common handler for parsing inputs */ +static int joycon_ctlr_read_handler(struct joycon_ctlr *ctlr, u8 *data, + int size) +{ + int ret = 0; + + if (data[0] == JC_INPUT_SUBCMD_REPLY || data[0] == JC_INPUT_IMU_DATA || + data[0] == JC_INPUT_MCU_DATA) { + if (size >= 12) /* make sure it contains the input report */ + joycon_parse_report(ctlr, + (struct joycon_input_report *)data); + } + + return ret; +} + +static int joycon_ctlr_handle_event(struct joycon_ctlr *ctlr, u8 *data, + int size) +{ + int ret = 0; + bool match = false; + struct joycon_input_report *report; + + if (unlikely(mutex_is_locked(&ctlr->output_mutex)) && + ctlr->msg_type != JOYCON_MSG_TYPE_NONE) { + switch (ctlr->msg_type) { + case JOYCON_MSG_TYPE_USB: + if (size < 2) + break; + if (data[0] == JC_INPUT_USB_RESPONSE && + data[1] == ctlr->usb_ack_match) + match = true; + break; + case JOYCON_MSG_TYPE_SUBCMD: + if (size < sizeof(struct joycon_input_report) || + data[0] != JC_INPUT_SUBCMD_REPLY) + break; + report = (struct joycon_input_report *)data; + if (report->reply.id == ctlr->subcmd_ack_match) + match = true; + break; + default: + break; + } + + if (match) { + memcpy(ctlr->input_buf, data, + min(size, (int)JC_MAX_RESP_SIZE)); + ctlr->msg_type = JOYCON_MSG_TYPE_NONE; + ctlr->received_resp = true; + wake_up(&ctlr->wait); + + /* This message has been handled */ + return 1; + } + } + + if (ctlr->ctlr_state == JOYCON_CTLR_STATE_READ) + ret = joycon_ctlr_read_handler(ctlr, data, size); + + return ret; +} + +static int nintendo_hid_event(struct hid_device *hdev, + struct hid_report *report, u8 *raw_data, int size) +{ + struct joycon_ctlr *ctlr = hid_get_drvdata(hdev); + + if (size < 1) + return -EINVAL; + + return joycon_ctlr_handle_event(ctlr, raw_data, size); +} + +static int nintendo_hid_probe(struct hid_device *hdev, + const struct hid_device_id *id) +{ + int ret; + struct joycon_ctlr *ctlr; + + hid_dbg(hdev, "probe - start\n"); + + ctlr = devm_kzalloc(&hdev->dev, sizeof(*ctlr), GFP_KERNEL); + if (!ctlr) { + ret = -ENOMEM; + goto err; + } + + ctlr->hdev = hdev; + ctlr->ctlr_state = JOYCON_CTLR_STATE_INIT; + hid_set_drvdata(hdev, ctlr); + mutex_init(&ctlr->output_mutex); + init_waitqueue_head(&ctlr->wait); + + ret = hid_parse(hdev); + if (ret) { + hid_err(hdev, "HID parse failed\n"); + goto err; + } + + ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW); + if (ret) { + hid_err(hdev, "HW start failed\n"); + goto err; + } + + ret = hid_hw_open(hdev); + if (ret) { + hid_err(hdev, "cannot start hardware I/O\n"); + goto err_stop; + } + + hid_device_io_start(hdev); + + /* Initialize the controller */ + mutex_lock(&ctlr->output_mutex); + /* if handshake command fails, assume ble pro controller */ + if (hdev->product == USB_DEVICE_ID_NINTENDO_PROCON && + !joycon_send_usb(ctlr, JC_USB_CMD_HANDSHAKE)) { + hid_dbg(hdev, "detected USB controller\n"); + /* set baudrate for improved latency */ + ret = joycon_send_usb(ctlr, JC_USB_CMD_BAUDRATE_3M); + if (ret) { + hid_err(hdev, "Failed to set baudrate; ret=%d\n", ret); + goto err_mutex; + } + /* handshake */ + ret = joycon_send_usb(ctlr, JC_USB_CMD_HANDSHAKE); + if (ret) { + hid_err(hdev, "Failed handshake; ret=%d\n", ret); + goto err_mutex; + } + /* + * Set no timeout (to keep controller in USB mode). + * This doesn't send a response, so ignore the timeout. + */ + joycon_send_usb(ctlr, JC_USB_CMD_NO_TIMEOUT); + } + + /* get controller calibration data, and parse it */ + ret = joycon_request_calibration(ctlr); + if (ret) { + /* + * We can function with default calibration, but it may be + * inaccurate. Provide a warning, and continue on. + */ + hid_warn(hdev, "Analog stick positions may be inaccurate\n"); + } + + /* Set the reporting mode to 0x30, which is the full report mode */ + ret = joycon_set_report_mode(ctlr); + if (ret) { + hid_err(hdev, "Failed to set report mode; ret=%d\n", ret); + goto err_mutex; + } + + mutex_unlock(&ctlr->output_mutex); + + ret = joycon_input_create(ctlr); + if (ret) { + hid_err(hdev, "Failed to create input device; ret=%d\n", ret); + goto err_close; + } + + ctlr->ctlr_state = JOYCON_CTLR_STATE_READ; + + hid_dbg(hdev, "probe - success\n"); + return 0; + +err_mutex: + mutex_unlock(&ctlr->output_mutex); +err_close: + hid_hw_close(hdev); +err_stop: + hid_hw_stop(hdev); +err: + hid_err(hdev, "probe - fail = %d\n", ret); + return ret; +} + +static void nintendo_hid_remove(struct hid_device *hdev) +{ + hid_dbg(hdev, "remove\n"); + hid_hw_close(hdev); + hid_hw_stop(hdev); +} + +static const struct hid_device_id nintendo_hid_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_NINTENDO, + USB_DEVICE_ID_NINTENDO_PROCON) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, + USB_DEVICE_ID_NINTENDO_PROCON) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, + USB_DEVICE_ID_NINTENDO_JOYCONL) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_NINTENDO, + USB_DEVICE_ID_NINTENDO_JOYCONR) }, + { } +}; +MODULE_DEVICE_TABLE(hid, nintendo_hid_devices); + +static struct hid_driver nintendo_hid_driver = { + .name = "nintendo", + .id_table = nintendo_hid_devices, + .probe = nintendo_hid_probe, + .remove = nintendo_hid_remove, + .raw_event = nintendo_hid_event, +}; +module_hid_driver(nintendo_hid_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Daniel J. Ogorchock "); +MODULE_DESCRIPTION("Driver for Nintendo Switch Controllers"); -- cgit v1.2.3 From ea1081dd437528ad32c536d074671074a56856f2 Mon Sep 17 00:00:00 2001 From: Swetha Chikkaboraiah Date: Fri, 4 Dec 2020 18:58:24 +0530 Subject: defconfig: Enable CONFIG_HID_NINTENDO for SDM660 Enable CONFIG_HID_NINTENDO for SDM660 device. Change-Id: I51e9a74d118b98b3f1a6e5c395174fe9494ce184 Signed-off-by: Swetha Chikkaboraiah --- arch/arm64/configs/sdm660-perf_defconfig | 1 + arch/arm64/configs/sdm660_defconfig | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm64/configs/sdm660-perf_defconfig b/arch/arm64/configs/sdm660-perf_defconfig index ba31684a574f..f676431f7c39 100644 --- a/arch/arm64/configs/sdm660-perf_defconfig +++ b/arch/arm64/configs/sdm660-perf_defconfig @@ -452,6 +452,7 @@ CONFIG_HID_ELECOM=y CONFIG_HID_MAGICMOUSE=y CONFIG_HID_MICROSOFT=y CONFIG_HID_MULTITOUCH=y +CONFIG_HID_NINTENDO=y CONFIG_HID_PLANTRONICS=y CONFIG_HID_SONY=y CONFIG_USB=y diff --git a/arch/arm64/configs/sdm660_defconfig b/arch/arm64/configs/sdm660_defconfig index 0478840268fc..a6d430cbc8e1 100644 --- a/arch/arm64/configs/sdm660_defconfig +++ b/arch/arm64/configs/sdm660_defconfig @@ -457,6 +457,7 @@ CONFIG_HID_ELECOM=y CONFIG_HID_MAGICMOUSE=y CONFIG_HID_MICROSOFT=y CONFIG_HID_MULTITOUCH=y +CONFIG_HID_NINTENDO=y CONFIG_HID_PLANTRONICS=y CONFIG_HID_SONY=y CONFIG_USB=y -- cgit v1.2.3 From 5e09017f84cf393dcc316d2955010a2f21beedb1 Mon Sep 17 00:00:00 2001 From: Swetha Chikkaboraiah Date: Wed, 23 Sep 2020 17:10:07 +0530 Subject: ARM: dts: msm: Enable vibrator in msm8998 DT support to enable vibrator in msm8998. Change-Id: I6f6ebd0f3d7a993c86ce6636b25984062ccf4c21 Signed-off-by: Swetha Chikkaboraiah --- arch/arm/boot/dts/qcom/msm-pmi8998.dtsi | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/arch/arm/boot/dts/qcom/msm-pmi8998.dtsi b/arch/arm/boot/dts/qcom/msm-pmi8998.dtsi index 4c049c8007cc..b710d5451bde 100644 --- a/arch/arm/boot/dts/qcom/msm-pmi8998.dtsi +++ b/arch/arm/boot/dts/qcom/msm-pmi8998.dtsi @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2017, 2020, 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 @@ -638,26 +638,25 @@ status = "okay"; }; - pmi8998_haptics: qcom,haptic@c000 { - status = "disabled"; - compatible = "qcom,qpnp-haptic"; + pmi8998_haptics: qcom,haptics@c000 { + compatible = "qcom,qpnp-haptics"; reg = <0xc000 0x100>; interrupts = <0x3 0xc0 0x0 IRQ_TYPE_EDGE_BOTH>, <0x3 0xc0 0x1 IRQ_TYPE_EDGE_BOTH>; - interrupt-names = "sc-irq", "play-irq"; + interrupt-names = "hap-sc-irq", "hap-play-irq"; qcom,pmic-revid = <&pmi8998_revid>; qcom,pmic-misc = <&pmi8998_misc>; qcom,misc-clk-trim-error-reg = <0xf3>; - qcom,actuator-type = "lra"; + qcom,int-pwm-freq-khz = <505>; qcom,play-mode = "direct"; + qcom,wave-play-rate-us = <6667>; + qcom,actuator-type = <0>; + qcom,wave-shape = "square"; qcom,vmax-mv = <3200>; qcom,ilim-ma = <800>; - qcom,wave-shape = "square"; - qcom,wave-play-rate-us = <6667>; - qcom,int-pwm-freq-khz = <505>; qcom,sc-deb-cycles = <8>; qcom,en-brake; - qcom,brake-pattern = [03 03 00 00]; + qcom,brake-pattern = <0x3 0x3 0x0 0x0>; qcom,lra-high-z = "opt1"; qcom,lra-auto-res-mode = "qwd"; qcom,lra-res-cal-period = <4>; -- cgit v1.2.3 From e347c9141e5698a3b48ee800d3db7d241c4ea177 Mon Sep 17 00:00:00 2001 From: Swetha Chikkaboraiah Date: Thu, 24 Sep 2020 13:09:17 +0530 Subject: defconfig: msm8998: enable LEDS_QPNP_HAPTICS Adding support LEDS_QPNP_HAPTICS driver for msm8998. Change-Id: I002b3683dd11ef64811a1954a508e9a09502a477 Signed-off-by: Swetha Chikkaboraiah --- arch/arm64/configs/msmcortex_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/msmcortex_defconfig b/arch/arm64/configs/msmcortex_defconfig index 81e70f0e42e0..a37953ad33c5 100644 --- a/arch/arm64/configs/msmcortex_defconfig +++ b/arch/arm64/configs/msmcortex_defconfig @@ -509,6 +509,7 @@ CONFIG_LEDS_QPNP=y CONFIG_LEDS_QPNP_FLASH_V2=y CONFIG_LEDS_QPNP_WLED=y CONFIG_LEDS_SYSCON=y +CONFIG_LEDS_QPNP_HAPTICS=y CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGER_HEARTBEAT=y CONFIG_LEDS_TRIGGER_CPU=y -- cgit v1.2.3 From f977eeb57cd20895d2550b4399632ae4e09122be Mon Sep 17 00:00:00 2001 From: Swetha Chikkaboraiah Date: Wed, 16 Dec 2020 14:39:25 +0530 Subject: HID: sony: Support PS4 BT This add sony PS4 Bluetooth support. Change-Id: Ia10c8e474a1d80ff5316aee14fe0c155fa9b743e Signed-off-by: Swetha Chikkaboraiah --- drivers/hid/hid-core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index b8cca99f36e6..d57b8b1abbe3 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -2054,6 +2054,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) }, { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER) }, { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_2) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_2) }, { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS4_CONTROLLER_DONGLE) }, -- cgit v1.2.3 From 1db0924b721fed066e9019e62591cde0a7b3aed2 Mon Sep 17 00:00:00 2001 From: Swetha Chikkaboraiah Date: Mon, 30 Nov 2020 13:18:39 +0530 Subject: defconfig: msm8998: enable LEDS_QPNP_HAPTICS Adding support LEDS_QPNP_HAPTICS driver for msm8998. Signed-off-by: Swetha Chikkaboraiah Change-Id: Ib54b981d140fc9ef3ae9fb533c57aeac3562dc44 --- arch/arm64/configs/msmcortex-perf_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/msmcortex-perf_defconfig b/arch/arm64/configs/msmcortex-perf_defconfig index c98953b95f9f..7bd9ddba5f49 100644 --- a/arch/arm64/configs/msmcortex-perf_defconfig +++ b/arch/arm64/configs/msmcortex-perf_defconfig @@ -501,6 +501,7 @@ CONFIG_LEDS_QPNP=y CONFIG_LEDS_QPNP_FLASH_V2=y CONFIG_LEDS_QPNP_WLED=y CONFIG_LEDS_SYSCON=y +CONFIG_LEDS_QPNP_HAPTICS=y CONFIG_LEDS_TRIGGERS=y CONFIG_SWITCH=y CONFIG_RTC_CLASS=y -- cgit v1.2.3 From 0427be586cf9a32339c8a851a1802f7d897cfb06 Mon Sep 17 00:00:00 2001 From: Shreyas Narayan Date: Thu, 17 Dec 2020 17:23:25 +0530 Subject: sdm660-perf_defconfig changes Change-Id: Ia887ce65f78dcd7f63d98091c6a0d641a988f18f Signed-off-by: Shreyas Narayan --- arch/arm64/configs/sdm660-perf_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm64/configs/sdm660-perf_defconfig b/arch/arm64/configs/sdm660-perf_defconfig index f676431f7c39..e25dcaf77552 100644 --- a/arch/arm64/configs/sdm660-perf_defconfig +++ b/arch/arm64/configs/sdm660-perf_defconfig @@ -507,6 +507,7 @@ CONFIG_LEDS_QPNP=y CONFIG_LEDS_QPNP_FLASH_V2=y CONFIG_LEDS_QPNP_WLED=y CONFIG_LEDS_SYSCON=y +CONFIG_LEDS_QPNP_HAPTICS=y CONFIG_LEDS_TRIGGERS=y CONFIG_SWITCH=y CONFIG_RTC_CLASS=y -- cgit v1.2.3