From nobody Sun May 24 19:33:55 2026 Received: from mail-ej1-f46.google.com (mail-ej1-f46.google.com [209.85.218.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 68B02374E76 for ; Sat, 23 May 2026 08:44:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779525869; cv=none; b=oHCRwisfdEUDMy2dbronbR1JC64ljm/l4u4L+vR6d2fshAs8hlfQ4EOS1h9qKWymOFWi4Qol545q86Eh0ze+DnYoJpV3coEMauoIG0iarpTde0Kpb4mhi7wof1zVl+n9b/Y3MDcofcUivHWtov6u0/v0wmqcu9TAWtdKfHM/1u8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779525869; c=relaxed/simple; bh=aCRvYddBbXrODXAsigivXkpsnAI8V+yb5mlCXcskyT4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HqDbicXZzMiQv3Y8iX8mCmEAiK67z6Rrrt6qcYLVp9vrK/msm6qDIFNcy08lBMp/n5fqf/SEk5hH0HCdyF0YoZKB5gKlSZjJlvUY3OazJ5s0ocsDvtJ6qqLQ4OI7ySBIXHjFDTzHltXG++U7dtIh1RhHotxRtbX0hjEK55a3JXM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=OAwhHM5J; arc=none smtp.client-ip=209.85.218.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="OAwhHM5J" Received: by mail-ej1-f46.google.com with SMTP id a640c23a62f3a-bd2087858c4so1557817666b.0 for ; Sat, 23 May 2026 01:44:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779525866; x=1780130666; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=7Qhj6rHOiahWvbVZuWT+FMPoy+y8UQ9yLqxFehsJ6oo=; b=OAwhHM5JqncDKe3JqEBG7ormYizSPXPfTRN/XxD0Wb1zPwzmhsedfWfsUSZ0Dgj7aL m3J3NFciv3Hj69N9HGgbmOkF6MA32KdzaEPMSY4mFDY6cyCVvDDuxaelUzM99TA2RmhS y3ompCB63rhwCR4EO257saawhyedKo3QZ8NaiPTmyFA9J5A8tzuqqXWLm8O3jg1TySFP ZIhSqUsVnFVmq+gYxDrlviTnxpAiWJNemtkKZKPvs1njM7ZB9Zlg+uPoSBk/2ynz45Wc SFRNiNgKyUiB6Sf7dDoyI+N/wp5vjHbzjslCONm5q7lgDj1Txd9tfpE+2oyYLWWbTR9B yOmQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779525866; x=1780130666; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=7Qhj6rHOiahWvbVZuWT+FMPoy+y8UQ9yLqxFehsJ6oo=; b=PuO0b5ITI2sdZY/gpZspqRb3u+Hlh8BR3d+91q+bEFe6Ls5Hy0sDIixhAXTD3tMk+T J4SRDyG3HV2f1VFDA06cabJ7nXve/rteVXvTJOSTTi0tS2oXgwkquiAW1qUusnMqguyF UtAL7I80JsoyCAGe9mCpbiY0vaubFAHNkQ7NExocr8ryqxkTKmGB33vSxhfk2bBQexpc 4ct5nFOy+WALAszwJJGSfq9Vf+N8vlWYPDBi/uOiW3VToQyDfAumcl4pQXSECLx8ONRl XdXBEM3PYTp2v1eo4K/PEShJw/nK2DxkaHuPd2pTaUVidL0hy+vV/DqPXYGSsTL4R894 JmEQ== X-Forwarded-Encrypted: i=1; AFNElJ+4AuvGR/Se/HrVPBzfxtBuslG9JRmfE4dEBRW2Bw+GR8k6fox5PlUr45EerV6fwmqZ59d6Ly6DyUcp9/w=@vger.kernel.org X-Gm-Message-State: AOJu0YxKgILPht+G3TuT95K9M8632No0nezWz+3Jdib7cviKhiyducNl ELEWaLdrQToaeCRDxtDUzSMlCg5cHWDtmN/stLfM2hdoQ90bfwtECB/7 X-Gm-Gg: Acq92OEYTagDOZ3m1varg+xG6kWhYlZTB+jU+qXLvGh9OPki0IVvSQzl68PA4ZOtcH7 gV9CQRSCHIK/+j4ArvP4k2keUVnUemEQuoJQ4KrKsEFBouMtmfdkxOfOTh7nHHZ81sgIpJQt/qE 9BxtpunEG294TJj+mJl+/WpacZOEKzdNPE9q5fwL7Gmf0nfrsZtU+x6219O8TaYHyB3wIqCTtht tlPFJP4Wy9E1vy3RJOSJlLDxZJrlXuqiVrqL2ePhXc3vcqtn6JNi+qalj+Jpjjm9NZ+xRnYUcJf dS8h18v6vqe29aXM2LeGjnSRzhz+TYFOMnBbJ1/7tG6UhKca44RnFyb2p42gRpQQ5i5aoRT75fG GlvXoGzALJUQNnc9O2BS9pLHjZBknkSpbJw/ENn0NICNIOVwvHVg+mTAr03VXm5gRp22Cb61MuC 4JcODwOAGlM0VX X-Received: by 2002:a17:906:4594:b0:b9d:e301:20db with SMTP id a640c23a62f3a-bdd274c9a91mr321047766b.25.1779525865586; Sat, 23 May 2026 01:44:25 -0700 (PDT) Received: from xeon ([188.163.112.61]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bddc62d70a5sm154042966b.48.2026.05.23.01.44.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 23 May 2026 01:44:25 -0700 (PDT) From: Svyatoslav Ryhel To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Svyatoslav Ryhel Cc: netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org Subject: [PATCH v2 1/2] dt-bindings: net: Document Infineon/Intel XMM6260 modem Date: Sat, 23 May 2026 11:44:06 +0300 Message-ID: <20260523084408.50346-2-clamor95@gmail.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260523084408.50346-1-clamor95@gmail.com> References: <20260523084408.50346-1-clamor95@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Describe the Infineon/Intel XMM6260, a 3G-focused, slim modem platform designed for smartphones, data cards, and Machine-to-Machine (M2M) applications. Signed-off-by: Svyatoslav Ryhel Reviewed-by: Krzysztof Kozlowski --- .../bindings/net/infineon,xmm6260.yaml | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 Documentation/devicetree/bindings/net/infineon,xmm6260.= yaml diff --git a/Documentation/devicetree/bindings/net/infineon,xmm6260.yaml b/= Documentation/devicetree/bindings/net/infineon,xmm6260.yaml new file mode 100644 index 000000000000..ffff58e479ef --- /dev/null +++ b/Documentation/devicetree/bindings/net/infineon,xmm6260.yaml @@ -0,0 +1,74 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/net/infineon,xmm6260.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Infineon/Intel XMM6260 embedded USB modem + +description: + The Infineon/Intel XMM6260 is a 3G-focused, slim modem platform designed + for smartphones, data cards, and Machine-to-Machine (M2M) applications. + The modem is usually connected via the application processor's USB line + in HSIC mode; however, to work properly, the modem must control this lin= e. + +maintainers: + - Svyatoslav Ryhel + +properties: + compatible: + const: infineon,xmm6260 + + interrupts: + maxItems: 1 + + enable-gpios: + description: GPIO connected to the ON1 pin + maxItems: 1 + + reset-gpios: + description: GPIO connected to the RESET_PWRDWN_N pin + maxItems: 1 + + ap-wake-gpios: + description: GPIO connected to the EINT3 pin + maxItems: 1 + + cp-wake-gpios: + description: GPIO connected to the EINT2 pin + maxItems: 1 + + vbat-supply: + description: Supply connected to the VBAT lines. + + infineon,modem-pwrseq: + description: + Contains phandle pointing to the modem's power sequence. + $ref: /schemas/types.yaml#/definitions/phandle + +required: + - compatible + - interrupts + +additionalProperties: false + +examples: + - | + #include + #include + + modem { + compatible =3D "infineon,xmm6260"; + + interrupt-parent =3D <&gpio>; + interrupts =3D <168 IRQ_TYPE_EDGE_BOTH>; + + enable-gpios =3D <&gpio 112 GPIO_ACTIVE_HIGH>; + reset-gpios =3D <&gpio 169 GPIO_ACTIVE_LOW>; + + cp-wake-gpios =3D <&gpio 151 GPIO_ACTIVE_HIGH>; + ap-wake-gpios =3D <&gpio 168 GPIO_ACTIVE_HIGH>; + + infineon,modem-pwrseq =3D <&xmm6260_modem_pwrseq>; + vbat-supply =3D <&vdd_3v3_vbat>; + }; --=20 2.51.0 From nobody Sun May 24 19:33:55 2026 Received: from mail-ej1-f52.google.com (mail-ej1-f52.google.com [209.85.218.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D9598372ED6 for ; Sat, 23 May 2026 08:44:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779525876; cv=none; b=OKOOgZQCpdTqCmzAUmglmePzWwqxX9DTFe30b1dfSMWzqqr2T6HgoAAGf+5jS33IUuBQyXAXuMWp3mBL+FKZz1mKdLPR4GuTNwACUlG0nj9Z+L6YvWt9K5/K2JeZ1b2gjGb9GKeOLJVmxd3GMQq1tZIOI4MZrzKwyO2G39+k+IM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779525876; c=relaxed/simple; bh=9oprkoi7DYWuhOMzKA+2R6TB07z0WZogt1+14SSTfkk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=p3bP142kAdLTZ1v2SBWsI2rrzDwta0jr055q95PaOzdyoha8BIV0dh8naOzpDaiV3VDnImpPS0tRMlQt3CB+iMtVNgXZdyvyco8ryJ43+NCz7vMOGzQEkNHCNvsKvmN1fUGMVIYqPYNPiejbaKcsv22Vdf8fnSJmuzJaClExINs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=lIjwluaq; arc=none smtp.client-ip=209.85.218.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="lIjwluaq" Received: by mail-ej1-f52.google.com with SMTP id a640c23a62f3a-bdbac72ac1fso527946466b.3 for ; Sat, 23 May 2026 01:44:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1779525869; x=1780130669; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=w4rV8mWsiC13Dx8VjcnY9lCfoJOx46rnsUI+A7HjLZs=; b=lIjwluaqBJDB/+VydAS4YfCvv30WMZgGPRPKmSCa+G0hQdkEb2KMZUwQ+94kSfhsJS GegRh2VHd5nLk1FcWaiUsUv7qdx0FkzRU2jlSSi7jYPNCN9diDoxnWLJ5nyNul2E12Q1 jNLR8n+HxIGGgsm932h+yLb6paRvrI58b6gEBXGrZ7NblPKV3HOYw5EYXRnj+fFu75vd ckY2hEjJraIIO58+03bgTDgZC+0oWFnCl6Hde/Hw3HugRQTJyaki8WyAIU7gBR7W+MlI QOHptVd74+xXeoE55vpQ6XYbWW5T5uy59xVUbaOVQDXkSWPAnTJb8hQheXrQG8zAKbrW ff2g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779525869; x=1780130669; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=w4rV8mWsiC13Dx8VjcnY9lCfoJOx46rnsUI+A7HjLZs=; b=K7wm5NaxLrIMrxOuKwN+Ar+2QPsGmTfGmp+kJluZraLatO+KOrr2nxdZCaWEogQuUn fvW2o2lwlSmE9amUtHkpwxSLoq0O5ro2HCIfSad5J0P7O9BHvgiL7jkcjucUwN6VDb67 XnK21xa4SHtwXGkP37fIQqfJYKGpOciN9qzdxM7G8uUieqSZJ8v9/9SGLndLA5Z3VK8u hh1lBr0I6/wwbdIJpKQ9xBqSl8LE/A6OYhFxKXRx3sPbwY5VlTTFC2xqBM+gU+p4bWMd dRWwI3xvqb+j9efhLRobURPdhvcFnVx2QSoTlXVaGZ4lJh0Yb3oPapu16gx/J2Dn5pF5 vKkQ== X-Forwarded-Encrypted: i=1; AFNElJ8jKentajw9npSq6G+px6YC5qYZ1YgZPR5h7Eeo9Kjc/7xN2v2kht0X+YDm/5mmQ1Ihn87tTtGAtO+9Rdk=@vger.kernel.org X-Gm-Message-State: AOJu0YxQ2l765ZP/QgJz86IKXijuYygyGavj6Nv08cMU+M/gF/l0kR1M WilyaQynZP3h8mffA8a6yjLWuqbBkpPcYzTy/N3QuYgpqlSTvkj1Na9k X-Gm-Gg: Acq92OFXPhsZvlJNyKd2VBbvQ87rsTpzK4yh73BWs5I5jiI4E44sX/lDqarlaH7W3NA t3m/L3DlwOMZM91GkonlcpisXKL3mgtE8dNk9gQXBfdSnJiPefsG8O63qv6gNVNxGVZvmixWRoy ReedBDaw+Pz0min8eNSFbqDRCdtxIp84YRlOTFIYdmMBPfreipk2jhzdGkQxf0USHvucdwXBMPc BcvLbuv13zxcpgGVEAhym/NFVPfuYxat13uExPT1xdYL/oiY8Irtdp7AGgfbkWt3SFXydUOW6VI pY81BpHS/MHcmnty0rJBxGuddexmP06LoCcd3KaXoOg1PRGsF4p2e87C/wo0qle4nFjV90mpJ2F iEzodv42ttVIigvLwcBOjYjcRzWTJi+JJT0eidyE9MnoXoWZ9F5xKLJnfGaDYbZ4IEYB4xl/BCE ygNWxRRbB+b84K X-Received: by 2002:a17:907:1c28:b0:bd6:6f5e:ea6f with SMTP id a640c23a62f3a-bdd237f5752mr401948666b.19.1779525869132; Sat, 23 May 2026 01:44:29 -0700 (PDT) Received: from xeon ([188.163.112.61]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-bddc62d70a5sm154042966b.48.2026.05.23.01.44.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 23 May 2026 01:44:27 -0700 (PDT) From: Svyatoslav Ryhel To: Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Svyatoslav Ryhel Cc: netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org Subject: [PATCH v2 2/2] net: usb: Add Infineon XMM6260 Baseband modem support Date: Sat, 23 May 2026 11:44:07 +0300 Message-ID: <20260523084408.50346-3-clamor95@gmail.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20260523084408.50346-1-clamor95@gmail.com> References: <20260523084408.50346-1-clamor95@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The Infineon/Intel XMM6260 is a 3G-focused, slim modem platform designed for smartphones, data cards, and Machine-to-Machine (M2M) applications. The modem is usually connected via the application processor's USB line in HSIC mode; however, to work properly, the modem must control this line Dmesg with modem appearing on LG Optimus Vu (P895): [ 9.427014] ci_hdrc ci_hdrc.1: EHCI Host Controller [ 9.431488] ci_hdrc ci_hdrc.1: new USB bus registered, assigned bus numb= er 1 [ 9.457197] ci_hdrc ci_hdrc.1: USB 2.0 started, EHCI 1.00 [ 9.460370] usb usb1: New USB device found, idVendor=3D1d6b, idProduct= =3D0002, bcdDevice=3D 6.16 [ 9.468470] usb usb1: New USB device strings: Mfr=3D3, Product=3D2, Seri= alNumber=3D1 [ 9.475597] usb usb1: Product: EHCI Host Controller [ 9.480508] usb usb1: Manufacturer: Linux 6.16.0+ ehci_hcd [ 9.485913] usb usb1: SerialNumber: ci_hdrc.1 [ 9.490862] hub 1-0:1.0: USB hub found [ 9.494005] hub 1-0:1.0: 1 port detected [ 9.657191] usb 1-1: new high-speed USB device number 2 using ci_hdrc [ 9.844726] usb 1-1: New USB device found, idVendor=3D1519, idProduct=3D= 0020, bcdDevice=3D12.74 [ 9.850530] usb 1-1: New USB device strings: Mfr=3D1, Product=3D2, Seria= lNumber=3D3 [ 9.857594] usb 1-1: Product: HSIC Device [ 9.861606] usb 1-1: Manufacturer: Comneon [ 9.865627] usb 1-1: SerialNumber: 0123456789 [ 9.908739] cdc_acm 1-1:1.0: ttyACM0: USB ACM device Signed-off-by: Svyatoslav Ryhel --- drivers/net/usb/Kconfig | 15 ++ drivers/net/usb/Makefile | 1 + drivers/net/usb/baseband-xmm6260.c | 378 +++++++++++++++++++++++++++++ 3 files changed, 394 insertions(+) create mode 100644 drivers/net/usb/baseband-xmm6260.c diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 52a5c0922c79..d54d8db752df 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -642,4 +642,19 @@ config USB_RTL8153_ECM CONFIG_USB_RTL8152 is not set, or the RTL8153 device is not supported by r8152 driver. =20 +config USB_NET_XMM6260 + tristate "Infineon XMM626X Baseband HSPA/HSUPA modem" + depends on USB_CHIPIDEA && (RFKILL || RFKILL=3Dn) + help + Select this if you want to use an Infineon XMM626X modem, found in + devices such as the LG Optimus 4X P880, LG Optimus Vu P895, Samsung + Galaxy S II (GT-I9100), and Galaxy Nexus (GT-I9250). This driver + handles the modem configuration and provides a stable way to expose + the modem's USB interface. To establish a connection, you will first + need a userspace program to send the correct commands to the modem + through its CDC ACM port, as well as a DHCP client. + + To compile this driver as a module, choose M here: the module will + be called baseband-xmm6260. + endif # USB_NET_DRIVERS diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index 4964f7b326fb..ffa532c7d7d6 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile @@ -42,3 +42,4 @@ obj-$(CONFIG_USB_NET_CDC_MBIM) +=3D cdc_mbim.o obj-$(CONFIG_USB_NET_CH9200) +=3D ch9200.o obj-$(CONFIG_USB_NET_AQC111) +=3D aqc111.o obj-$(CONFIG_USB_RTL8153_ECM) +=3D r8153_ecm.o +obj-$(CONFIG_USB_NET_XMM6260) +=3D baseband-xmm6260.o diff --git a/drivers/net/usb/baseband-xmm6260.c b/drivers/net/usb/baseband-= xmm6260.c new file mode 100644 index 000000000000..557ec79f5e2a --- /dev/null +++ b/drivers/net/usb/baseband-xmm6260.c @@ -0,0 +1,378 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2011 NVIDIA Corporation + * Copyright (C) 2023 Svyatoslav Ryhel + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BASEBAND_XMM_INIT_DELAY 5000 + +#define BASEBAND_PRODUCT_ID_XMM6260 0x0020 +#define BASEBAND_VENDOR_ID_COMNEON 0x1519 + +/* + * Starting from ver 1145 modem starts in the IPC_AP_WAKE_IRQ_READY state. + * AP wake interrupt keeps low util CP starts to initiate its HSIC hw. AP = wake + * interrupt goes up during CP HSIC init (BASEBAND_XMM_IPC_AP_WAKE_INIT1 s= tate) + * at this point Host USB bus must be configured in order for modem to set + * properly. Then interrupt goes down when CP HSIC is ready + * (BASEBAND_XMM_IPC_AP_WAKE_INIT2 state) and at this point XMM6260 USB de= vice + * should appear and be accessible for further work. In case it does not, = the + * cycle must repeat. + */ + +/* bits [0:2] */ +enum baseband_xmm_ipc_ap_wake_state { + BASEBAND_XMM_IPC_AP_WAKE_IRQ_READY, + BASEBAND_XMM_IPC_AP_WAKE_INIT1, + BASEBAND_XMM_IPC_AP_WAKE_INIT2, + BASEBAND_XMM_IPC_AP_WAKE_L, + BASEBAND_XMM_IPC_AP_WAKE_H, + BASEBAND_XMM_IPC_AP_WAKE_UNINIT, + BASEBAND_XMM_IPC_AP_WAKE_MASK =3D 7, +}; + +#define BASEBAND_XMM_IPC_AP_WAKE_MAX 3 + +#define BASEBAND_XMM_STATE_POWERED 3 /* Tracks regulator state */ +#define BASEBAND_XMM_STATE_PROTECTED 4 /* Prevents rfkill from access */ +#define BASEBAND_XMM_STATE_PRESENT 5 /* Tracks USB device presence */ +#define BASEBAND_XMM_STATE_POWEROFF 6 /* Prevents poweroff recursive call = */ +#define BASEBAND_XMM_STATE_MAX 8 + +struct baseband_xmm_data { + struct device *dev; + struct rfkill *rfkill_dev; + struct pwrseq_desc *pwrseq; + + DECLARE_BITMAP(state, BASEBAND_XMM_STATE_MAX); + int irq; + + struct gpio_desc *reset_gpio; + struct gpio_desc *enable_gpio; + + struct gpio_desc *ipc_cp_gpio; + struct gpio_desc *ipc_ap_gpio; + + struct regulator *vbat_supply; + + struct delayed_work modem_work; + struct notifier_block nb; +}; + +static int get_ipc_ap_wake(struct baseband_xmm_data *priv) +{ + int i, ret =3D 0; + + for (i =3D 0; i < BASEBAND_XMM_IPC_AP_WAKE_MAX; i++) + ret |=3D (test_bit(i, priv->state) << i); + + return ret; +} + +static void set_ipc_ap_wake(struct baseband_xmm_data *priv, + enum baseband_xmm_ipc_ap_wake_state state) +{ + for (int i =3D 0; i < BASEBAND_XMM_IPC_AP_WAKE_MAX; i++) + if (state & BIT(i)) + set_bit(i, priv->state); + else + clear_bit(i, priv->state); +} + +static void baseband_xmm_reset(struct baseband_xmm_data *priv) +{ + int ret; + + set_bit(BASEBAND_XMM_STATE_PROTECTED, priv->state); + + if (!test_bit(BASEBAND_XMM_STATE_POWERED, priv->state)) { + ret =3D regulator_enable(priv->vbat_supply); + if (ret) + dev_err(priv->dev, + "failed to enable vbat power supply\n"); + + set_bit(BASEBAND_XMM_STATE_POWERED, priv->state); + } + + gpiod_set_value_cansleep(priv->enable_gpio, 0); + msleep(50); + + gpiod_set_value_cansleep(priv->reset_gpio, 1); + msleep(200); + gpiod_set_value_cansleep(priv->reset_gpio, 0); + + msleep(50); + + /* falling edge trigger to CP */ + gpiod_set_value_cansleep(priv->enable_gpio, 1); + usleep_range(50, 100); + gpiod_set_value_cansleep(priv->enable_gpio, 0); + msleep(20); +} + +static void baseband_xmm_poweroff(struct baseband_xmm_data *priv) +{ + /* + * The test_bit check prevents poweroff from being recursively + * called during USB device deregistration. USB device + * deregistration can be triggered by the driver by calling this + * function or by some external event. The first case will cause + * a recursive call by the notifier if not handled, while the + * second case requires this call to handle the USB controller + * properly. + */ + if (test_bit(BASEBAND_XMM_STATE_POWEROFF, priv->state)) + return; + + set_bit(BASEBAND_XMM_STATE_PROTECTED, priv->state); + set_bit(BASEBAND_XMM_STATE_POWEROFF, priv->state); + + pwrseq_power_off(priv->pwrseq); + gpiod_set_value_cansleep(priv->reset_gpio, 1); + + if (test_bit(BASEBAND_XMM_STATE_POWERED, priv->state)) { + regulator_disable(priv->vbat_supply); + clear_bit(BASEBAND_XMM_STATE_POWERED, priv->state); + } + set_ipc_ap_wake(priv, BASEBAND_XMM_IPC_AP_WAKE_IRQ_READY); + + clear_bit(BASEBAND_XMM_STATE_PROTECTED, priv->state); + clear_bit(BASEBAND_XMM_STATE_PRESENT, priv->state); + clear_bit(BASEBAND_XMM_STATE_POWEROFF, priv->state); +} + +static int baseband_xmm_usb_notifier_call(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct baseband_xmm_data *priv =3D + container_of(nb, struct baseband_xmm_data, nb); + struct usb_device *udev; + u16 product, vendor; + + if (action =3D=3D USB_BUS_ADD || action =3D=3D USB_BUS_REMOVE) + return NOTIFY_OK; + + udev =3D data; + product =3D le16_to_cpu(udev->descriptor.idProduct); + vendor =3D le16_to_cpu(udev->descriptor.idVendor); + + switch (action) { + case USB_DEVICE_ADD: + /* Infineon XMM6260 ID 1519:0020 */ + if (vendor =3D=3D BASEBAND_VENDOR_ID_COMNEON && + product =3D=3D BASEBAND_PRODUCT_ID_XMM6260) { + cancel_delayed_work_sync(&priv->modem_work); + clear_bit(BASEBAND_XMM_STATE_PROTECTED, priv->state); + set_bit(BASEBAND_XMM_STATE_PRESENT, priv->state); + } + break; + + case USB_DEVICE_REMOVE: + /* Infineon XMM6260 ID 1519:0020 */ + if (vendor =3D=3D BASEBAND_VENDOR_ID_COMNEON && + product =3D=3D BASEBAND_PRODUCT_ID_XMM6260) + baseband_xmm_poweroff(priv); + break; + + default: + break; + } + + return NOTIFY_OK; +} + +static int baseband_xmm_set_block(void *data, bool blocked) +{ + struct baseband_xmm_data *priv =3D data; + + if (test_bit(BASEBAND_XMM_STATE_PROTECTED, priv->state)) + return -EBUSY; + + if (blocked && test_bit(BASEBAND_XMM_STATE_PRESENT, priv->state)) + baseband_xmm_poweroff(priv); + else if (!blocked && !test_bit(BASEBAND_XMM_STATE_PRESENT, priv->state)) + baseband_xmm_reset(priv); + + return 0; +} + +static const struct rfkill_ops baseband_xmm_rfkill_ops =3D { + .set_block =3D baseband_xmm_set_block, +}; + +static void baseband_xmm_work(struct work_struct *work) +{ + struct baseband_xmm_data *priv =3D + container_of(work, struct baseband_xmm_data, modem_work.work); + + baseband_xmm_poweroff(priv); +}; + +static irqreturn_t baseband_hostwake_interrupt(int irq, void *dev_id) +{ + struct baseband_xmm_data *priv =3D dev_id; + int state =3D gpiod_get_value(priv->ipc_ap_gpio); + + switch (get_ipc_ap_wake(priv)) { + case BASEBAND_XMM_IPC_AP_WAKE_IRQ_READY: + if (!state) { + set_ipc_ap_wake(priv, BASEBAND_XMM_IPC_AP_WAKE_INIT1); + pwrseq_power_on(priv->pwrseq); + } + break; + + case BASEBAND_XMM_IPC_AP_WAKE_INIT1: + if (state) { + set_ipc_ap_wake(priv, BASEBAND_XMM_IPC_AP_WAKE_INIT2); + schedule_delayed_work(&priv->modem_work, + msecs_to_jiffies(BASEBAND_XMM_INIT_DELAY)); + } + break; + + default: + break; + } + + return IRQ_HANDLED; +} + +static int baseband_xmm_probe(struct platform_device *pdev) +{ + struct baseband_xmm_data *priv; + struct device *dev =3D &pdev->dev; + unsigned long irqflags; + int ret; + + priv =3D devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->dev =3D dev; + platform_set_drvdata(pdev, priv); + + priv->vbat_supply =3D devm_regulator_get(dev, "vbat"); + if (IS_ERR(priv->vbat_supply)) + return dev_err_probe(dev, PTR_ERR(priv->vbat_supply), + "failed to get vbat regulator\n"); + + /* Own modem gpios */ + priv->reset_gpio =3D devm_gpiod_get_optional(dev, "reset", + GPIOD_OUT_LOW); + if (IS_ERR(priv->reset_gpio)) + return dev_err_probe(dev, PTR_ERR(priv->reset_gpio), + "failed to get reset GPIO\n"); + + priv->enable_gpio =3D devm_gpiod_get_optional(dev, "enable", + GPIOD_OUT_LOW); + if (IS_ERR(priv->enable_gpio)) + return dev_err_probe(dev, PTR_ERR(priv->enable_gpio), + "failed to get enable GPIO\n"); + + /* CP - AP connections */ + priv->ipc_cp_gpio =3D devm_gpiod_get_optional(dev, "cp-wake", + GPIOD_OUT_LOW); + if (IS_ERR(priv->ipc_cp_gpio)) + return dev_err_probe(dev, PTR_ERR(priv->ipc_cp_gpio), + "failed to get CP wake GPIO\n"); + + priv->ipc_ap_gpio =3D devm_gpiod_get_optional(dev, "ap-wake", GPIOD_IN); + if (IS_ERR(priv->ipc_ap_gpio)) + return dev_err_probe(dev, PTR_ERR(priv->ipc_ap_gpio), + "failed to get AP wake GPIO\n"); + + /* Modem power sequence */ + priv->pwrseq =3D devm_pwrseq_get(dev, "modem-power"); + if (IS_ERR(priv->pwrseq)) + return dev_err_probe(dev, PTR_ERR(priv->pwrseq), + "failed to get modem pwrseq"); + + bitmap_zero(priv->state, BASEBAND_XMM_STATE_MAX); + INIT_DELAYED_WORK(&priv->modem_work, baseband_xmm_work); + + priv->irq =3D platform_get_irq(pdev, 0); + if (priv->irq < 0) + return dev_err_probe(dev, priv->irq, "failed to get IRQ\n"); + + /* + * Systems using device tree should set up interrupt via DT, + * the rest will use the default edge both interrupt. + */ + irqflags =3D dev->of_node ? 0 : IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLIN= G; + + ret =3D devm_request_threaded_irq(dev, priv->irq, NULL, + &baseband_hostwake_interrupt, + IRQF_ONESHOT | irqflags, + "modem-hostwake", priv); + if (ret) + return dev_err_probe(dev, ret, + "failed to register IRQ %d\n", priv->irq); + + priv->rfkill_dev =3D rfkill_alloc("xmm-modem", dev, RFKILL_TYPE_WWAN, + &baseband_xmm_rfkill_ops, priv); + if (!priv->rfkill_dev) + return -ENOMEM; + + ret =3D rfkill_register(priv->rfkill_dev); + if (ret) { + rfkill_destroy(priv->rfkill_dev); + return dev_err_probe(dev, ret, + "failed to register WWAN rfkill\n"); + } + + priv->nb.notifier_call =3D baseband_xmm_usb_notifier_call; + usb_register_notify(&priv->nb); + + return 0; +} + +static void baseband_xmm_remove(struct platform_device *pdev) +{ + struct baseband_xmm_data *priv =3D platform_get_drvdata(pdev); + + rfkill_unregister(priv->rfkill_dev); + rfkill_destroy(priv->rfkill_dev); + + disable_irq(priv->irq); + cancel_delayed_work_sync(&priv->modem_work); + + usb_unregister_notify(&priv->nb); + baseband_xmm_poweroff(priv); +} + +static const struct of_device_id baseband_xmm_match[] =3D { + { .compatible =3D "infineon,xmm6260" }, + { } +}; +MODULE_DEVICE_TABLE(of, baseband_xmm_match); + +static struct platform_driver baseband_xmm_driver =3D { + .driver =3D { + .name =3D "baseband-xmm6260", + .of_match_table =3D baseband_xmm_match, + }, + .probe =3D baseband_xmm_probe, + .remove =3D baseband_xmm_remove, +}; +module_platform_driver(baseband_xmm_driver); + +MODULE_AUTHOR("Svyatolsav Ryhel "); +MODULE_DESCRIPTION("Baseband Infineon XMM6260 driver"); +MODULE_LICENSE("GPL"); --=20 2.51.0