Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'extcon-next-for-6.18' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/chanwoo/extcon into char-misc-next

Chanwoo writes:

Update extcon next for v6.18

Detailed description for this pull request:
- Fix wakeup source leaks on device unbind for extcon drivers

- Add new Maxim MAX14526 MUIC extcon driver and dt-binding document
: The MAX14526 is designed to simplify interface requirements on portable
devices by multiplexing common inputs (USB, UART, Microphone, Stereo Audio
and Composite Video) on a single micro/mini USB connector. The USB input
supports Hi-Speed USB and the audio/video inputs feature
: This provides the following supported external connector detection
- EXTCON_USB
- EXTCON_USB_HOST
- EXTCON_CHG_USB_FAST
- EXTCON_DISP_MHL

- Convert legacy DT binding to YAML of richktek,rt8973a-muic.yaml

- Add missing DT binding information of that must include either id-gpios or
vbus-gpios for linux,extcon-usb-gpio.yaml

* tag 'extcon-next-for-6.18' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/chanwoo/extcon:
dt-bindings: extcon: linux,extcon-usb-gpio: GPIO must be provided
dt-bindings: extcon: rt8973a: Convert DT bindings to YAML
extcon: max14526: depends on I2C to prevent build warning/errors
extcon: max14526: avoid defined but not used warning
extcon: Add basic support for Maxim MAX14526 MUIC
dt-bindings: extcon: Document Maxim MAX14526 MUIC
extcon: adc-jack: Cleanup wakeup source only if it was enabled
extcon: qcom-spmi-misc: Fix wakeup source leaks on device unbind
extcon: fsa9480: Fix wakeup source leaks on device unbind
extcon: axp288: Fix wakeup source leaks on device unbind
extcon: adc-jack: Fix wakeup source leaks on device unbind

+456 -26
-23
Documentation/devicetree/bindings/extcon/extcon-rt8973a.txt
··· 1 - 2 - * Richtek RT8973A - Micro USB Switch device 3 - 4 - The Richtek RT8973A is Micro USB Switch with OVP and I2C interface. The RT8973A 5 - is a USB port accessory detector and switch that is optimized to protect low 6 - voltage system from abnormal high input voltage (up to 28V) and supports high 7 - speed USB operation. Also, RT8973A support 'auto-configuration' mode. 8 - If auto-configuration mode is enabled, RT8973A would control internal h/w patch 9 - for USB D-/D+ switching. 10 - 11 - Required properties: 12 - - compatible: Should be "richtek,rt8973a-muic" 13 - - reg: Specifies the I2C slave address of the MUIC block. It should be 0x14 14 - - interrupts: Interrupt specifiers for detection interrupt sources. 15 - 16 - Example: 17 - 18 - rt8973a@14 { 19 - compatible = "richtek,rt8973a-muic"; 20 - interrupt-parent = <&gpx1>; 21 - interrupts = <5 0>; 22 - reg = <0x14>; 23 - };
+6
Documentation/devicetree/bindings/extcon/linux,extcon-usb-gpio.yaml
··· 25 25 required: 26 26 - compatible 27 27 28 + anyOf: 29 + - required: 30 + - id-gpios 31 + - required: 32 + - vbus-gpios 33 + 28 34 additionalProperties: false 29 35 30 36 examples:
+80
Documentation/devicetree/bindings/extcon/maxim,max14526.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/extcon/maxim,max14526.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Maxim MAX14526 MicroUSB Integrated Circuit (MUIC) 8 + 9 + maintainers: 10 + - Svyatoslav Ryhel <clamor95@gmail.com> 11 + 12 + properties: 13 + compatible: 14 + const: maxim,max14526 15 + 16 + reg: 17 + maxItems: 1 18 + 19 + interrupts: 20 + maxItems: 1 21 + 22 + connector: 23 + $ref: /schemas/connector/usb-connector.yaml# 24 + 25 + port: 26 + $ref: /schemas/graph.yaml#/properties/port 27 + 28 + required: 29 + - compatible 30 + - reg 31 + - interrupts 32 + - connector 33 + - port 34 + 35 + unevaluatedProperties: false 36 + 37 + examples: 38 + - | 39 + #include <dt-bindings/gpio/gpio.h> 40 + #include <dt-bindings/interrupt-controller/irq.h> 41 + 42 + i2c { 43 + #address-cells = <1>; 44 + #size-cells = <0>; 45 + 46 + muic@44 { 47 + compatible = "maxim,max14526"; 48 + reg = <0x44>; 49 + 50 + interrupt-parent = <&gpio>; 51 + interrupts = <72 IRQ_TYPE_EDGE_FALLING>; 52 + 53 + connector { 54 + compatible = "usb-b-connector"; 55 + label = "micro-USB"; 56 + type = "micro"; 57 + }; 58 + 59 + port { 60 + #address-cells = <1>; 61 + #size-cells = <0>; 62 + 63 + muic_to_charger: endpoint@0 { 64 + reg = <0>; 65 + remote-endpoint = <&charger_input>; 66 + }; 67 + 68 + muic_to_usb: endpoint@1 { 69 + reg = <1>; 70 + remote-endpoint = <&usb_input>; 71 + }; 72 + 73 + muic_to_mhl: endpoint@2 { 74 + reg = <2>; 75 + remote-endpoint = <&mhl_input>; 76 + }; 77 + }; 78 + }; 79 + }; 80 + ...
+49
Documentation/devicetree/bindings/extcon/richtek,rt8973a-muic.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/extcon/richtek,rt8973a-muic.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Richtek RT8973A MUIC 8 + 9 + maintainers: 10 + - Chanwoo Choi <cw00.choi@samsung.com> 11 + 12 + description: 13 + The Richtek RT8973A is Micro USB Switch with OVP and I2C interface. The RT8973A 14 + is a USB port accessory detector and switch that is optimized to protect low 15 + voltage system from abnormal high input voltage (up to 28V) and supports high 16 + speed USB operation. Also, RT8973A support 'auto-configuration' mode. 17 + If auto-configuration mode is enabled, RT8973A would control internal h/w patch 18 + for USB D-/D+ switching. 19 + 20 + properties: 21 + compatible: 22 + const: richtek,rt8973a-muic 23 + 24 + reg: 25 + maxItems: 1 26 + 27 + interrupts: 28 + maxItems: 1 29 + 30 + required: 31 + - compatible 32 + - reg 33 + - interrupts 34 + 35 + additionalProperties: false 36 + 37 + examples: 38 + - | 39 + #include <dt-bindings/interrupt-controller/irq.h> 40 + i2c { 41 + #address-cells = <1>; 42 + #size-cells = <0>; 43 + usb-switch@14 { 44 + compatible = "richtek,rt8973a-muic"; 45 + reg = <0x14>; 46 + interrupt-parent = <&gpio>; 47 + interrupts = <1 IRQ_TYPE_EDGE_FALLING>; 48 + }; 49 + };
+13
drivers/extcon/Kconfig
··· 134 134 Maxim MAX8997 PMIC. The MAX8997 MUIC is a USB port accessory 135 135 detector and switch. 136 136 137 + config EXTCON_MAX14526 138 + tristate "Maxim MAX14526 EXTCON Support" 139 + depends on I2C 140 + select IRQ_DOMAIN 141 + select REGMAP_I2C 142 + help 143 + If you say yes here you get support for the Maxim MAX14526 144 + MUIC device. The MAX14526 MUIC is a USB port accessory 145 + detector and switch. The MAX14526 is designed to simplify 146 + interface requirements on portable devices by multiplexing 147 + common inputs (USB, UART, Microphone, Stereo Audio and 148 + Composite Video) on a single micro/mini USB connector. 149 + 137 150 config EXTCON_PALMAS 138 151 tristate "Palmas USB EXTCON support" 139 152 depends on MFD_PALMAS
+1
drivers/extcon/Makefile
··· 18 18 obj-$(CONFIG_EXTCON_MAX77693) += extcon-max77693.o 19 19 obj-$(CONFIG_EXTCON_MAX77843) += extcon-max77843.o 20 20 obj-$(CONFIG_EXTCON_MAX8997) += extcon-max8997.o 21 + obj-$(CONFIG_EXTCON_MAX14526) += extcon-max14526.o 21 22 obj-$(CONFIG_EXTCON_PALMAS) += extcon-palmas.o 22 23 obj-$(CONFIG_EXTCON_PTN5150) += extcon-ptn5150.o 23 24 obj-$(CONFIG_EXTCON_QCOM_SPMI_MISC) += extcon-qcom-spmi-misc.o
+2
drivers/extcon/extcon-adc-jack.c
··· 164 164 { 165 165 struct adc_jack_data *data = platform_get_drvdata(pdev); 166 166 167 + if (data->wakeup_source) 168 + device_init_wakeup(&pdev->dev, false); 167 169 free_irq(data->irq, data); 168 170 cancel_work_sync(&data->handler.work); 169 171 }
+1 -1
drivers/extcon/extcon-axp288.c
··· 470 470 if (ret < 0) 471 471 return ret; 472 472 473 - device_init_wakeup(dev, true); 473 + devm_device_init_wakeup(dev); 474 474 platform_set_drvdata(pdev, info); 475 475 476 476 return 0;
+1 -1
drivers/extcon/extcon-fsa9480.c
··· 317 317 return ret; 318 318 } 319 319 320 - device_init_wakeup(info->dev, true); 320 + devm_device_init_wakeup(info->dev); 321 321 fsa9480_detect_dev(info); 322 322 323 323 return 0;
+302
drivers/extcon/extcon-max14526.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + 3 + #include <linux/device.h> 4 + #include <linux/devm-helpers.h> 5 + #include <linux/delay.h> 6 + #include <linux/err.h> 7 + #include <linux/extcon-provider.h> 8 + #include <linux/i2c.h> 9 + #include <linux/mod_devicetable.h> 10 + #include <linux/interrupt.h> 11 + #include <linux/module.h> 12 + #include <linux/pm.h> 13 + #include <linux/regmap.h> 14 + 15 + /* I2C addresses of MUIC internal registers */ 16 + #define MAX14526_DEVICE_ID 0x00 17 + #define MAX14526_ID 0x02 18 + 19 + /* CONTROL_1 register masks */ 20 + #define MAX14526_CONTROL_1 0x01 21 + #define ID_2P2 BIT(6) 22 + #define ID_620 BIT(5) 23 + #define ID_200 BIT(4) 24 + #define VLDO BIT(3) 25 + #define SEMREN BIT(2) 26 + #define ADC_EN BIT(1) 27 + #define CP_EN BIT(0) 28 + 29 + /* CONTROL_2 register masks */ 30 + #define MAX14526_CONTROL_2 0x02 31 + #define INTPOL BIT(7) 32 + #define INT_EN BIT(6) 33 + #define MIC_LP BIT(5) 34 + #define CP_AUD BIT(4) 35 + #define CHG_TYPE BIT(1) 36 + #define USB_DET_DIS BIT(0) 37 + 38 + /* SW_CONTROL register masks */ 39 + #define MAX14526_SW_CONTROL 0x03 40 + #define SW_DATA 0x00 41 + #define SW_UART 0x01 42 + #define SW_AUDIO 0x02 43 + #define SW_OPEN 0x07 44 + 45 + /* INT_STATUS register masks */ 46 + #define MAX14526_INT_STAT 0x04 47 + #define CHGDET BIT(7) 48 + #define MR_COMP BIT(6) 49 + #define SENDEND BIT(5) 50 + #define V_VBUS BIT(4) 51 + 52 + /* STATUS register masks */ 53 + #define MAX14526_STATUS 0x05 54 + #define CPORT BIT(7) 55 + #define CHPORT BIT(6) 56 + #define C1COMP BIT(0) 57 + 58 + enum max14526_idno_resistance { 59 + MAX14526_GND, 60 + MAX14526_24KOHM, 61 + MAX14526_56KOHM, 62 + MAX14526_100KOHM, 63 + MAX14526_130KOHM, 64 + MAX14526_180KOHM, 65 + MAX14526_240KOHM, 66 + MAX14526_330KOHM, 67 + MAX14526_430KOHM, 68 + MAX14526_620KOHM, 69 + MAX14526_910KOHM, 70 + MAX14526_OPEN 71 + }; 72 + 73 + enum max14526_field_idx { 74 + VENDOR_ID, CHIP_REV, /* DEVID */ 75 + DM, DP, /* SW_CONTROL */ 76 + MAX14526_N_REGMAP_FIELDS 77 + }; 78 + 79 + static const struct reg_field max14526_reg_field[MAX14526_N_REGMAP_FIELDS] = { 80 + [VENDOR_ID] = REG_FIELD(MAX14526_DEVICE_ID, 4, 7), 81 + [CHIP_REV] = REG_FIELD(MAX14526_DEVICE_ID, 0, 3), 82 + [DM] = REG_FIELD(MAX14526_SW_CONTROL, 0, 2), 83 + [DP] = REG_FIELD(MAX14526_SW_CONTROL, 3, 5), 84 + }; 85 + 86 + struct max14526_data { 87 + struct i2c_client *client; 88 + struct extcon_dev *edev; 89 + 90 + struct regmap *regmap; 91 + struct regmap_field *rfield[MAX14526_N_REGMAP_FIELDS]; 92 + 93 + int last_state; 94 + int cable; 95 + }; 96 + 97 + enum max14526_muic_modes { 98 + MAX14526_OTG = MAX14526_GND, /* no power */ 99 + MAX14526_MHL = MAX14526_56KOHM, /* no power */ 100 + MAX14526_OTG_Y = MAX14526_GND | V_VBUS, 101 + MAX14526_MHL_CHG = MAX14526_GND | V_VBUS | CHGDET, 102 + MAX14526_NONE = MAX14526_OPEN, 103 + MAX14526_USB = MAX14526_OPEN | V_VBUS, 104 + MAX14526_CHG = MAX14526_OPEN | V_VBUS | CHGDET, 105 + }; 106 + 107 + static const unsigned int max14526_extcon_cable[] = { 108 + EXTCON_USB, 109 + EXTCON_USB_HOST, 110 + EXTCON_CHG_USB_FAST, 111 + EXTCON_DISP_MHL, 112 + EXTCON_NONE, 113 + }; 114 + 115 + static int max14526_ap_usb_mode(struct max14526_data *priv) 116 + { 117 + struct device *dev = &priv->client->dev; 118 + int ret; 119 + 120 + /* Enable USB Path */ 121 + ret = regmap_field_write(priv->rfield[DM], SW_DATA); 122 + if (ret) 123 + return ret; 124 + 125 + ret = regmap_field_write(priv->rfield[DP], SW_DATA); 126 + if (ret) 127 + return ret; 128 + 129 + /* Enable 200K, Charger Pump and ADC */ 130 + ret = regmap_write(priv->regmap, MAX14526_CONTROL_1, 131 + ID_200 | ADC_EN | CP_EN); 132 + if (ret) 133 + return ret; 134 + 135 + dev_dbg(dev, "AP USB mode set\n"); 136 + 137 + return 0; 138 + } 139 + 140 + static irqreturn_t max14526_interrupt(int irq, void *dev_id) 141 + { 142 + struct max14526_data *priv = dev_id; 143 + struct device *dev = &priv->client->dev; 144 + int state, ret; 145 + 146 + /* 147 + * Upon an MUIC IRQ (MUIC_INT_N falls), wait at least 70ms 148 + * before reading INT_STAT and STATUS. After the reads, 149 + * MUIC_INT_N returns to high (but the INT_STAT and STATUS 150 + * contents will be held). 151 + */ 152 + msleep(100); 153 + 154 + ret = regmap_read(priv->regmap, MAX14526_INT_STAT, &state); 155 + if (ret) 156 + dev_err(dev, "failed to read MUIC state %d\n", ret); 157 + 158 + if (state == priv->last_state) 159 + return IRQ_HANDLED; 160 + 161 + /* Detach previous device */ 162 + extcon_set_state_sync(priv->edev, priv->cable, false); 163 + 164 + switch (state) { 165 + case MAX14526_USB: 166 + priv->cable = EXTCON_USB; 167 + break; 168 + 169 + case MAX14526_CHG: 170 + priv->cable = EXTCON_CHG_USB_FAST; 171 + break; 172 + 173 + case MAX14526_OTG: 174 + case MAX14526_OTG_Y: 175 + priv->cable = EXTCON_USB_HOST; 176 + break; 177 + 178 + case MAX14526_MHL: 179 + case MAX14526_MHL_CHG: 180 + priv->cable = EXTCON_DISP_MHL; 181 + break; 182 + 183 + case MAX14526_NONE: 184 + default: 185 + priv->cable = EXTCON_NONE; 186 + break; 187 + } 188 + 189 + extcon_set_state_sync(priv->edev, priv->cable, true); 190 + 191 + priv->last_state = state; 192 + 193 + return IRQ_HANDLED; 194 + } 195 + 196 + static const struct regmap_config max14526_regmap_config = { 197 + .reg_bits = 8, 198 + .val_bits = 8, 199 + .max_register = MAX14526_STATUS, 200 + }; 201 + 202 + static int max14526_probe(struct i2c_client *client) 203 + { 204 + struct device *dev = &client->dev; 205 + struct max14526_data *priv; 206 + int ret, dev_id, rev, i; 207 + 208 + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 209 + if (!priv) 210 + return -ENOMEM; 211 + 212 + priv->client = client; 213 + i2c_set_clientdata(client, priv); 214 + 215 + priv->regmap = devm_regmap_init_i2c(client, &max14526_regmap_config); 216 + if (IS_ERR(priv->regmap)) 217 + return dev_err_probe(dev, PTR_ERR(priv->regmap), "cannot allocate regmap\n"); 218 + 219 + for (i = 0; i < MAX14526_N_REGMAP_FIELDS; i++) { 220 + priv->rfield[i] = devm_regmap_field_alloc(dev, priv->regmap, 221 + max14526_reg_field[i]); 222 + if (IS_ERR(priv->rfield[i])) 223 + return dev_err_probe(dev, PTR_ERR(priv->rfield[i]), 224 + "cannot allocate regmap field\n"); 225 + } 226 + 227 + /* Detect if MUIC version is supported */ 228 + ret = regmap_field_read(priv->rfield[VENDOR_ID], &dev_id); 229 + if (ret) 230 + return dev_err_probe(dev, ret, "failed to read MUIC ID\n"); 231 + 232 + regmap_field_read(priv->rfield[CHIP_REV], &rev); 233 + 234 + if (dev_id == MAX14526_ID) 235 + dev_info(dev, "detected MAX14526 MUIC with id 0x%x, rev 0x%x\n", dev_id, rev); 236 + else 237 + dev_err_probe(dev, -EINVAL, "MUIC vendor id 0x%X is not recognized\n", dev_id); 238 + 239 + priv->edev = devm_extcon_dev_allocate(dev, max14526_extcon_cable); 240 + if (IS_ERR(priv->edev)) 241 + return dev_err_probe(dev, (IS_ERR(priv->edev)), 242 + "failed to allocate extcon device\n"); 243 + 244 + ret = devm_extcon_dev_register(dev, priv->edev); 245 + if (ret < 0) 246 + return dev_err_probe(dev, ret, "failed to register extcon device\n"); 247 + 248 + ret = max14526_ap_usb_mode(priv); 249 + if (ret < 0) 250 + return dev_err_probe(dev, ret, "failed to set AP USB mode\n"); 251 + 252 + regmap_write_bits(priv->regmap, MAX14526_CONTROL_2, INT_EN, INT_EN); 253 + regmap_write_bits(priv->regmap, MAX14526_CONTROL_2, USB_DET_DIS, (u32)~USB_DET_DIS); 254 + 255 + ret = devm_request_threaded_irq(dev, client->irq, NULL, &max14526_interrupt, 256 + IRQF_ONESHOT | IRQF_SHARED, client->name, priv); 257 + if (ret) 258 + return dev_err_probe(dev, ret, "failed to register IRQ\n"); 259 + 260 + irq_wake_thread(client->irq, priv); 261 + 262 + return 0; 263 + } 264 + 265 + static int max14526_resume(struct device *dev) 266 + { 267 + struct i2c_client *client = to_i2c_client(dev); 268 + struct max14526_data *priv = i2c_get_clientdata(client); 269 + 270 + irq_wake_thread(client->irq, priv); 271 + 272 + return 0; 273 + } 274 + 275 + static DEFINE_SIMPLE_DEV_PM_OPS(max14526_pm_ops, NULL, max14526_resume); 276 + 277 + static const struct of_device_id max14526_match[] = { 278 + { .compatible = "maxim,max14526" }, 279 + { /* sentinel */ } 280 + }; 281 + MODULE_DEVICE_TABLE(of, max14526_match); 282 + 283 + static const struct i2c_device_id max14526_id[] = { 284 + { "max14526" }, 285 + { } 286 + }; 287 + MODULE_DEVICE_TABLE(i2c, max14526_id); 288 + 289 + static struct i2c_driver max14526_driver = { 290 + .driver = { 291 + .name = "max14526", 292 + .of_match_table = max14526_match, 293 + .pm = &max14526_pm_ops, 294 + }, 295 + .probe = max14526_probe, 296 + .id_table = max14526_id, 297 + }; 298 + module_i2c_driver(max14526_driver); 299 + 300 + MODULE_AUTHOR("Svyatoslav Ryhel <clamor95@gmail.com>"); 301 + MODULE_DESCRIPTION("MAX14526 extcon driver to support MUIC"); 302 + MODULE_LICENSE("GPL");
+1 -1
drivers/extcon/extcon-qcom-spmi-misc.c
··· 155 155 } 156 156 157 157 platform_set_drvdata(pdev, info); 158 - device_init_wakeup(dev, 1); 158 + devm_device_init_wakeup(dev); 159 159 160 160 /* Perform initial detection */ 161 161 qcom_usb_extcon_detect_cable(&info->wq_detcable.work);