* [PATCH v2 0/6] extcon: sm5502: Add support for SM5504
@ 2021-05-31 13:34 Stephan Gerhold
2021-05-31 13:34 ` [PATCH v2 1/6] extcon: sm5502: Use devm_regmap_add_irq_chip() Stephan Gerhold
` (6 more replies)
0 siblings, 7 replies; 10+ messages in thread
From: Stephan Gerhold @ 2021-05-31 13:34 UTC (permalink / raw)
To: Chanwoo Choi, MyungJoo Ham
Cc: Rob Herring, devicetree, linux-kernel, Nikita Travkin,
~postmarketos/upstreaming, Stephan Gerhold
This patch series adds support for SM5504 to the existing extcon-sm5502
driver. SM5502 and SM5504 are fairly similar so support for SM5504 can
be added with a few simple if statements in the code.
I also put a few cleanup patches in front and convert the device tree
bindings to DT schema.
I tested this patch series on both SM5502 (Samsung Galaxy A5 2015)
and SM5504 (Samsung Galaxy S4 Mini Value Edition) and it seems to work
just fine for both.
---
Changes in v2: Fix compile warning in last patch
v1: https://lore.kernel.org/lkml/20210520112334.129556-1-stephan@gerhold.net/
Stephan Gerhold (6):
extcon: sm5502: Use devm_regmap_add_irq_chip()
extcon: sm5502: Implement i2c_driver->probe_new()
extcon: sm5502: Drop invalid register write in sm5502_reg_data
dt-bindings: extcon: sm5502: Convert to DT schema
dt-bindings: extcon: sm5502: Document siliconmitus,sm5504-muic
extcon: sm5502: Add support for SM5504
.../bindings/extcon/extcon-sm5502.txt | 21 --
.../extcon/siliconmitus,sm5502-muic.yaml | 52 +++++
drivers/extcon/Kconfig | 2 +-
drivers/extcon/extcon-sm5502.c | 180 +++++++++++++++---
drivers/extcon/extcon-sm5502.h | 79 ++++++++
5 files changed, 282 insertions(+), 52 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/extcon/extcon-sm5502.txt
create mode 100644 Documentation/devicetree/bindings/extcon/siliconmitus,sm5502-muic.yaml
--
2.31.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2 1/6] extcon: sm5502: Use devm_regmap_add_irq_chip()
2021-05-31 13:34 [PATCH v2 0/6] extcon: sm5502: Add support for SM5504 Stephan Gerhold
@ 2021-05-31 13:34 ` Stephan Gerhold
2021-05-31 13:34 ` [PATCH v2 2/6] extcon: sm5502: Implement i2c_driver->probe_new() Stephan Gerhold
` (5 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Stephan Gerhold @ 2021-05-31 13:34 UTC (permalink / raw)
To: Chanwoo Choi, MyungJoo Ham
Cc: Rob Herring, devicetree, linux-kernel, Nikita Travkin,
~postmarketos/upstreaming, Stephan Gerhold
Use devm_regmap_add_irq_chip() to avoid having to remove the
irqchip explicitly in sm5502_muic_i2c_remove().
Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
---
drivers/extcon/extcon-sm5502.c | 14 ++------------
1 file changed, 2 insertions(+), 12 deletions(-)
diff --git a/drivers/extcon/extcon-sm5502.c b/drivers/extcon/extcon-sm5502.c
index db41d1c58efd..f0d155cf7518 100644
--- a/drivers/extcon/extcon-sm5502.c
+++ b/drivers/extcon/extcon-sm5502.c
@@ -600,8 +600,8 @@ static int sm5022_muic_i2c_probe(struct i2c_client *i2c,
/* Support irq domain for SM5502 MUIC device */
irq_flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT | IRQF_SHARED;
- ret = regmap_add_irq_chip(info->regmap, info->irq, irq_flags, 0,
- &sm5502_muic_irq_chip, &info->irq_data);
+ ret = devm_regmap_add_irq_chip(info->dev, info->regmap, info->irq, irq_flags,
+ 0, &sm5502_muic_irq_chip, &info->irq_data);
if (ret != 0) {
dev_err(info->dev, "failed to request IRQ %d: %d\n",
info->irq, ret);
@@ -661,15 +661,6 @@ static int sm5022_muic_i2c_probe(struct i2c_client *i2c,
return 0;
}
-static int sm5502_muic_i2c_remove(struct i2c_client *i2c)
-{
- struct sm5502_muic_info *info = i2c_get_clientdata(i2c);
-
- regmap_del_irq_chip(info->irq, info->irq_data);
-
- return 0;
-}
-
static const struct of_device_id sm5502_dt_match[] = {
{ .compatible = "siliconmitus,sm5502-muic" },
{ },
@@ -714,7 +705,6 @@ static struct i2c_driver sm5502_muic_i2c_driver = {
.of_match_table = sm5502_dt_match,
},
.probe = sm5022_muic_i2c_probe,
- .remove = sm5502_muic_i2c_remove,
.id_table = sm5502_i2c_id,
};
--
2.31.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 2/6] extcon: sm5502: Implement i2c_driver->probe_new()
2021-05-31 13:34 [PATCH v2 0/6] extcon: sm5502: Add support for SM5504 Stephan Gerhold
2021-05-31 13:34 ` [PATCH v2 1/6] extcon: sm5502: Use devm_regmap_add_irq_chip() Stephan Gerhold
@ 2021-05-31 13:34 ` Stephan Gerhold
2021-05-31 13:34 ` [PATCH v2 3/6] extcon: sm5502: Drop invalid register write in sm5502_reg_data Stephan Gerhold
` (4 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Stephan Gerhold @ 2021-05-31 13:34 UTC (permalink / raw)
To: Chanwoo Choi, MyungJoo Ham
Cc: Rob Herring, devicetree, linux-kernel, Nikita Travkin,
~postmarketos/upstreaming, Stephan Gerhold
sm5022_muic_i2c_probe() does not use the i2c_device_id,
so implement i2c_driver->probe_new() instead of probe().
Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
---
drivers/extcon/extcon-sm5502.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/extcon/extcon-sm5502.c b/drivers/extcon/extcon-sm5502.c
index f0d155cf7518..907ecd01ebb7 100644
--- a/drivers/extcon/extcon-sm5502.c
+++ b/drivers/extcon/extcon-sm5502.c
@@ -563,8 +563,7 @@ static void sm5502_init_dev_type(struct sm5502_muic_info *info)
}
}
-static int sm5022_muic_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int sm5022_muic_i2c_probe(struct i2c_client *i2c)
{
struct device_node *np = i2c->dev.of_node;
struct sm5502_muic_info *info;
@@ -704,7 +703,7 @@ static struct i2c_driver sm5502_muic_i2c_driver = {
.pm = &sm5502_muic_pm_ops,
.of_match_table = sm5502_dt_match,
},
- .probe = sm5022_muic_i2c_probe,
+ .probe_new = sm5022_muic_i2c_probe,
.id_table = sm5502_i2c_id,
};
--
2.31.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 3/6] extcon: sm5502: Drop invalid register write in sm5502_reg_data
2021-05-31 13:34 [PATCH v2 0/6] extcon: sm5502: Add support for SM5504 Stephan Gerhold
2021-05-31 13:34 ` [PATCH v2 1/6] extcon: sm5502: Use devm_regmap_add_irq_chip() Stephan Gerhold
2021-05-31 13:34 ` [PATCH v2 2/6] extcon: sm5502: Implement i2c_driver->probe_new() Stephan Gerhold
@ 2021-05-31 13:34 ` Stephan Gerhold
2021-05-31 13:34 ` [PATCH v2 4/6] dt-bindings: extcon: sm5502: Convert to DT schema Stephan Gerhold
` (3 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Stephan Gerhold @ 2021-05-31 13:34 UTC (permalink / raw)
To: Chanwoo Choi, MyungJoo Ham
Cc: Rob Herring, devicetree, linux-kernel, Nikita Travkin,
~postmarketos/upstreaming, Stephan Gerhold
When sm5502_init_dev_type() iterates over sm5502_reg_data to
initialize the registers it is limited by ARRAY_SIZE(sm5502_reg_data).
There is no need to add another empty element to sm5502_reg_data.
Having the additional empty element in sm5502_reg_data will just
result in writing 0xff to register 0x00, which does not really
make sense.
Fixes: 914b881f9452 ("extcon: sm5502: Add support new SM5502 extcon device driver")
Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
---
drivers/extcon/extcon-sm5502.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/extcon/extcon-sm5502.c b/drivers/extcon/extcon-sm5502.c
index 907ecd01ebb7..9f40bb9f1f81 100644
--- a/drivers/extcon/extcon-sm5502.c
+++ b/drivers/extcon/extcon-sm5502.c
@@ -88,7 +88,6 @@ static struct reg_data sm5502_reg_data[] = {
| SM5502_REG_INTM2_MHL_MASK,
.invert = true,
},
- { }
};
/* List of detectable cables */
--
2.31.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 4/6] dt-bindings: extcon: sm5502: Convert to DT schema
2021-05-31 13:34 [PATCH v2 0/6] extcon: sm5502: Add support for SM5504 Stephan Gerhold
` (2 preceding siblings ...)
2021-05-31 13:34 ` [PATCH v2 3/6] extcon: sm5502: Drop invalid register write in sm5502_reg_data Stephan Gerhold
@ 2021-05-31 13:34 ` Stephan Gerhold
2021-06-02 16:48 ` Rob Herring
2021-05-31 13:34 ` [PATCH v2 5/6] dt-bindings: extcon: sm5502: Document siliconmitus,sm5504-muic Stephan Gerhold
` (2 subsequent siblings)
6 siblings, 1 reply; 10+ messages in thread
From: Stephan Gerhold @ 2021-05-31 13:34 UTC (permalink / raw)
To: Chanwoo Choi, MyungJoo Ham
Cc: Rob Herring, devicetree, linux-kernel, Nikita Travkin,
~postmarketos/upstreaming, Stephan Gerhold
Convert the extcon-sm5502 device tree bindings to DT schema.
Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
---
.../bindings/extcon/extcon-sm5502.txt | 21 --------
.../extcon/siliconmitus,sm5502-muic.yaml | 50 +++++++++++++++++++
2 files changed, 50 insertions(+), 21 deletions(-)
delete mode 100644 Documentation/devicetree/bindings/extcon/extcon-sm5502.txt
create mode 100644 Documentation/devicetree/bindings/extcon/siliconmitus,sm5502-muic.yaml
diff --git a/Documentation/devicetree/bindings/extcon/extcon-sm5502.txt b/Documentation/devicetree/bindings/extcon/extcon-sm5502.txt
deleted file mode 100644
index fc3888e09549..000000000000
--- a/Documentation/devicetree/bindings/extcon/extcon-sm5502.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-
-* SM5502 MUIC (Micro-USB Interface Controller) device
-
-The Silicon Mitus SM5502 is a MUIC (Micro-USB Interface Controller) device
-which can detect the state of external accessory when external accessory is
-attached or detached and button is pressed or released. It is interfaced to
-the host controller using an I2C interface.
-
-Required properties:
-- compatible: Should be "siliconmitus,sm5502-muic"
-- reg: Specifies the I2C slave address of the MUIC block. It should be 0x25
-- interrupts: Interrupt specifiers for detection interrupt sources.
-
-Example:
-
- sm5502@25 {
- compatible = "siliconmitus,sm5502-muic";
- interrupt-parent = <&gpx1>;
- interrupts = <5 0>;
- reg = <0x25>;
- };
diff --git a/Documentation/devicetree/bindings/extcon/siliconmitus,sm5502-muic.yaml b/Documentation/devicetree/bindings/extcon/siliconmitus,sm5502-muic.yaml
new file mode 100644
index 000000000000..0432b0502e0b
--- /dev/null
+++ b/Documentation/devicetree/bindings/extcon/siliconmitus,sm5502-muic.yaml
@@ -0,0 +1,50 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/extcon/siliconmitus,sm5502-muic.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: SM5502 MUIC (Micro-USB Interface Controller) device
+
+maintainers:
+ - Chanwoo Choi <cw00.choi@samsung.com>
+
+description:
+ The Silicon Mitus SM5502 is a MUIC (Micro-USB Interface Controller) device
+ which can detect the state of external accessory when external accessory is
+ attached or detached and button is pressed or released. It is interfaced to
+ the host controller using an I2C interface.
+
+properties:
+ compatible:
+ enum:
+ - siliconmitus,sm5502-muic
+
+ reg:
+ maxItems: 1
+ description: I2C slave address of the device. Usually 0x25 for SM5502.
+
+ interrupts:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+ - interrupts
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ extcon@25 {
+ compatible = "siliconmitus,sm5502-muic";
+ reg = <0x25>;
+ interrupt-parent = <&msmgpio>;
+ interrupts = <12 IRQ_TYPE_EDGE_FALLING>;
+ };
+ };
--
2.31.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 5/6] dt-bindings: extcon: sm5502: Document siliconmitus,sm5504-muic
2021-05-31 13:34 [PATCH v2 0/6] extcon: sm5502: Add support for SM5504 Stephan Gerhold
` (3 preceding siblings ...)
2021-05-31 13:34 ` [PATCH v2 4/6] dt-bindings: extcon: sm5502: Convert to DT schema Stephan Gerhold
@ 2021-05-31 13:34 ` Stephan Gerhold
2021-05-31 13:34 ` [PATCH v2 6/6] extcon: sm5502: Add support for SM5504 Stephan Gerhold
2021-06-01 16:28 ` [PATCH v2 0/6] " Chanwoo Choi
6 siblings, 0 replies; 10+ messages in thread
From: Stephan Gerhold @ 2021-05-31 13:34 UTC (permalink / raw)
To: Chanwoo Choi, MyungJoo Ham
Cc: Rob Herring, devicetree, linux-kernel, Nikita Travkin,
~postmarketos/upstreaming, Stephan Gerhold
Document support for SM5504 with the new siliconmitus,sm5504-muic
compatible.
Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
---
.../bindings/extcon/siliconmitus,sm5502-muic.yaml | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/extcon/siliconmitus,sm5502-muic.yaml b/Documentation/devicetree/bindings/extcon/siliconmitus,sm5502-muic.yaml
index 0432b0502e0b..fd2e55088888 100644
--- a/Documentation/devicetree/bindings/extcon/siliconmitus,sm5502-muic.yaml
+++ b/Documentation/devicetree/bindings/extcon/siliconmitus,sm5502-muic.yaml
@@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/extcon/siliconmitus,sm5502-muic.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
-title: SM5502 MUIC (Micro-USB Interface Controller) device
+title: SM5502/SM5504 MUIC (Micro-USB Interface Controller) device
maintainers:
- Chanwoo Choi <cw00.choi@samsung.com>
@@ -19,10 +19,12 @@ properties:
compatible:
enum:
- siliconmitus,sm5502-muic
+ - siliconmitus,sm5504-muic
reg:
maxItems: 1
- description: I2C slave address of the device. Usually 0x25 for SM5502.
+ description: I2C slave address of the device. Usually 0x25 for SM5502,
+ 0x14 for SM5504.
interrupts:
maxItems: 1
--
2.31.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 6/6] extcon: sm5502: Add support for SM5504
2021-05-31 13:34 [PATCH v2 0/6] extcon: sm5502: Add support for SM5504 Stephan Gerhold
` (4 preceding siblings ...)
2021-05-31 13:34 ` [PATCH v2 5/6] dt-bindings: extcon: sm5502: Document siliconmitus,sm5504-muic Stephan Gerhold
@ 2021-05-31 13:34 ` Stephan Gerhold
2021-06-01 16:27 ` Chanwoo Choi
2021-06-01 16:28 ` [PATCH v2 0/6] " Chanwoo Choi
6 siblings, 1 reply; 10+ messages in thread
From: Stephan Gerhold @ 2021-05-31 13:34 UTC (permalink / raw)
To: Chanwoo Choi, MyungJoo Ham
Cc: Rob Herring, devicetree, linux-kernel, Nikita Travkin,
~postmarketos/upstreaming, Stephan Gerhold
SM5504 is another MUIC from Silicon Mitus that is fairly similar
to SM5502. They seem to use the same register set, but:
- SM5504 has some additional bits in SM5502_REG_CONTROL
- SM5504 has a quite different set of interrupts
- SM5504 reports USB OTG as dev_type1 = BIT(0) instead of BIT(7)
Overall it's minor and we can support this using the existing
enum sm5502_types plus a few switch/if statements.
Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
---
Changes in v2: Fix warning: cast to smaller integer type 'enum sm5502_types'
from 'const void *' [-Wvoid-pointer-to-enum-cast]
reported by kernel test robot
Interestingly enough the register set (and especially the interrupts)
also look *very* similar to Richtek RT8973A (extcon-rt8973a) but
I didn't investigate this further.
Note that the changes in this patch are mostly based on guesswork
based on a SM5504 driver from Nitin Chaudhary [1] used in some Samsung
vendor kernels, since I was not able to find a public datasheet for SM5504.
[1]: https://github.com/NitinChaudharyUSC/MSM8x16_8x26/blob/master/drivers/misc/sm5504.c
---
drivers/extcon/Kconfig | 2 +-
drivers/extcon/extcon-sm5502.c | 164 +++++++++++++++++++++++++++++----
drivers/extcon/extcon-sm5502.h | 79 ++++++++++++++++
3 files changed, 228 insertions(+), 17 deletions(-)
diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig
index e3db936becfd..c69d40ae5619 100644
--- a/drivers/extcon/Kconfig
+++ b/drivers/extcon/Kconfig
@@ -154,7 +154,7 @@ config EXTCON_RT8973A
from abnormal high input voltage (up to 28V).
config EXTCON_SM5502
- tristate "Silicon Mitus SM5502 EXTCON support"
+ tristate "Silicon Mitus SM5502/SM5504 EXTCON support"
depends on I2C
select IRQ_DOMAIN
select REGMAP_I2C
diff --git a/drivers/extcon/extcon-sm5502.c b/drivers/extcon/extcon-sm5502.c
index 9f40bb9f1f81..49a35db61112 100644
--- a/drivers/extcon/extcon-sm5502.c
+++ b/drivers/extcon/extcon-sm5502.c
@@ -40,6 +40,7 @@ struct sm5502_muic_info {
struct i2c_client *i2c;
struct regmap *regmap;
+ enum sm5502_types type;
struct regmap_irq_chip_data *irq_data;
struct muic_irq *muic_irqs;
unsigned int num_muic_irqs;
@@ -90,6 +91,33 @@ static struct reg_data sm5502_reg_data[] = {
},
};
+/* Default value of SM5504 register to bring up MUIC device. */
+static struct reg_data sm5504_reg_data[] = {
+ {
+ .reg = SM5502_REG_RESET,
+ .val = SM5502_REG_RESET_MASK,
+ .invert = true,
+ }, {
+ .reg = SM5502_REG_INTMASK1,
+ .val = SM5504_REG_INTM1_ATTACH_MASK
+ | SM5504_REG_INTM1_DETACH_MASK,
+ .invert = false,
+ }, {
+ .reg = SM5502_REG_INTMASK2,
+ .val = SM5504_REG_INTM2_RID_CHG_MASK
+ | SM5504_REG_INTM2_UVLO_MASK
+ | SM5504_REG_INTM2_POR_MASK,
+ .invert = true,
+ }, {
+ .reg = SM5502_REG_CONTROL,
+ .val = SM5502_REG_CONTROL_MANUAL_SW_MASK
+ | SM5504_REG_CONTROL_CHGTYP_MASK
+ | SM5504_REG_CONTROL_USBCHDEN_MASK
+ | SM5504_REG_CONTROL_ADC_EN_MASK,
+ .invert = true,
+ },
+};
+
/* List of detectable cables */
static const unsigned int sm5502_extcon_cable[] = {
EXTCON_USB,
@@ -198,6 +226,55 @@ static const struct regmap_irq_chip sm5502_muic_irq_chip = {
.num_irqs = ARRAY_SIZE(sm5502_irqs),
};
+/* List of supported interrupt for SM5504 */
+static struct muic_irq sm5504_muic_irqs[] = {
+ { SM5504_IRQ_INT1_ATTACH, "muic-attach" },
+ { SM5504_IRQ_INT1_DETACH, "muic-detach" },
+ { SM5504_IRQ_INT1_CHG_DET, "muic-chg-det" },
+ { SM5504_IRQ_INT1_DCD_OUT, "muic-dcd-out" },
+ { SM5504_IRQ_INT1_OVP_EVENT, "muic-ovp-event" },
+ { SM5504_IRQ_INT1_CONNECT, "muic-connect" },
+ { SM5504_IRQ_INT1_ADC_CHG, "muic-adc-chg" },
+ { SM5504_IRQ_INT2_RID_CHG, "muic-rid-chg" },
+ { SM5504_IRQ_INT2_UVLO, "muic-uvlo" },
+ { SM5504_IRQ_INT2_POR, "muic-por" },
+ { SM5504_IRQ_INT2_OVP_FET, "muic-ovp-fet" },
+ { SM5504_IRQ_INT2_OCP_LATCH, "muic-ocp-latch" },
+ { SM5504_IRQ_INT2_OCP_EVENT, "muic-ocp-event" },
+ { SM5504_IRQ_INT2_OVP_OCP_EVENT, "muic-ovp-ocp-event" },
+};
+
+/* Define interrupt list of SM5504 to register regmap_irq */
+static const struct regmap_irq sm5504_irqs[] = {
+ /* INT1 interrupts */
+ { .reg_offset = 0, .mask = SM5504_IRQ_INT1_ATTACH_MASK, },
+ { .reg_offset = 0, .mask = SM5504_IRQ_INT1_DETACH_MASK, },
+ { .reg_offset = 0, .mask = SM5504_IRQ_INT1_CHG_DET_MASK, },
+ { .reg_offset = 0, .mask = SM5504_IRQ_INT1_DCD_OUT_MASK, },
+ { .reg_offset = 0, .mask = SM5504_IRQ_INT1_OVP_MASK, },
+ { .reg_offset = 0, .mask = SM5504_IRQ_INT1_CONNECT_MASK, },
+ { .reg_offset = 0, .mask = SM5504_IRQ_INT1_ADC_CHG_MASK, },
+
+ /* INT2 interrupts */
+ { .reg_offset = 1, .mask = SM5504_IRQ_INT2_RID_CHG_MASK,},
+ { .reg_offset = 1, .mask = SM5504_IRQ_INT2_UVLO_MASK, },
+ { .reg_offset = 1, .mask = SM5504_IRQ_INT2_POR_MASK, },
+ { .reg_offset = 1, .mask = SM5504_IRQ_INT2_OVP_FET_MASK, },
+ { .reg_offset = 1, .mask = SM5504_IRQ_INT2_OCP_LATCH_MASK, },
+ { .reg_offset = 1, .mask = SM5504_IRQ_INT2_OCP_EVENT_MASK, },
+ { .reg_offset = 1, .mask = SM5504_IRQ_INT2_OVP_OCP_EVENT_MASK, },
+};
+
+static const struct regmap_irq_chip sm5504_muic_irq_chip = {
+ .name = "sm5504",
+ .status_base = SM5502_REG_INT1,
+ .mask_base = SM5502_REG_INTMASK1,
+ .mask_invert = false,
+ .num_regs = 2,
+ .irqs = sm5504_irqs,
+ .num_irqs = ARRAY_SIZE(sm5504_irqs),
+};
+
/* Define regmap configuration of SM5502 for I2C communication */
static bool sm5502_muic_volatile_reg(struct device *dev, unsigned int reg)
{
@@ -276,9 +353,14 @@ static int sm5502_muic_set_path(struct sm5502_muic_info *info,
/* Return cable type of attached or detached accessories */
static unsigned int sm5502_muic_get_cable_type(struct sm5502_muic_info *info)
{
- unsigned int cable_type, adc, dev_type1;
+ unsigned int cable_type, adc, dev_type1, otg_dev_type1;
int ret;
+ if (info->type == TYPE_SM5504)
+ otg_dev_type1 = SM5504_REG_DEV_TYPE1_USB_OTG_MASK;
+ else
+ otg_dev_type1 = SM5502_REG_DEV_TYPE1_USB_OTG_MASK;
+
/* Read ADC value according to external cable or button */
ret = regmap_read(info->regmap, SM5502_REG_ADC, &adc);
if (ret) {
@@ -301,11 +383,9 @@ static unsigned int sm5502_muic_get_cable_type(struct sm5502_muic_info *info)
return ret;
}
- switch (dev_type1) {
- case SM5502_REG_DEV_TYPE1_USB_OTG_MASK:
+ if (dev_type1 == otg_dev_type1) {
cable_type = SM5502_MUIC_ADC_GROUND_USB_OTG;
- break;
- default:
+ } else {
dev_dbg(info->dev,
"cannot identify the cable type: adc(0x%x), dev_type1(0x%x)\n",
adc, dev_type1);
@@ -358,6 +438,11 @@ static unsigned int sm5502_muic_get_cable_type(struct sm5502_muic_info *info)
return ret;
}
+ if (dev_type1 == otg_dev_type1) {
+ cable_type = SM5502_MUIC_ADC_OPEN_USB_OTG;
+ break;
+ }
+
switch (dev_type1) {
case SM5502_REG_DEV_TYPE1_USB_SDP_MASK:
cable_type = SM5502_MUIC_ADC_OPEN_USB;
@@ -365,9 +450,6 @@ static unsigned int sm5502_muic_get_cable_type(struct sm5502_muic_info *info)
case SM5502_REG_DEV_TYPE1_DEDICATED_CHG_MASK:
cable_type = SM5502_MUIC_ADC_OPEN_TA;
break;
- case SM5502_REG_DEV_TYPE1_USB_OTG_MASK:
- cable_type = SM5502_MUIC_ADC_OPEN_USB_OTG;
- break;
default:
dev_dbg(info->dev,
"cannot identify the cable type: adc(0x%x)\n",
@@ -497,6 +579,34 @@ static int sm5502_parse_irq(struct sm5502_muic_info *info, int irq_type)
return 0;
}
+static int sm5504_parse_irq(struct sm5502_muic_info *info, int irq_type)
+{
+ switch (irq_type) {
+ case SM5504_IRQ_INT1_ATTACH:
+ info->irq_attach = true;
+ break;
+ case SM5504_IRQ_INT1_DETACH:
+ info->irq_detach = true;
+ break;
+ case SM5504_IRQ_INT1_CHG_DET:
+ case SM5504_IRQ_INT1_DCD_OUT:
+ case SM5504_IRQ_INT1_OVP_EVENT:
+ case SM5504_IRQ_INT1_CONNECT:
+ case SM5504_IRQ_INT1_ADC_CHG:
+ case SM5504_IRQ_INT2_RID_CHG:
+ case SM5504_IRQ_INT2_UVLO:
+ case SM5504_IRQ_INT2_POR:
+ case SM5504_IRQ_INT2_OVP_FET:
+ case SM5504_IRQ_INT2_OCP_LATCH:
+ case SM5504_IRQ_INT2_OCP_EVENT:
+ case SM5504_IRQ_INT2_OVP_OCP_EVENT:
+ default:
+ break;
+ }
+
+ return 0;
+}
+
static irqreturn_t sm5502_muic_irq_handler(int irq, void *data)
{
struct sm5502_muic_info *info = data;
@@ -506,7 +616,10 @@ static irqreturn_t sm5502_muic_irq_handler(int irq, void *data)
if (irq == info->muic_irqs[i].virq)
irq_type = info->muic_irqs[i].irq;
- ret = sm5502_parse_irq(info, irq_type);
+ if (info->type == TYPE_SM5504)
+ ret = sm5504_parse_irq(info, irq_type);
+ else
+ ret = sm5502_parse_irq(info, irq_type);
if (ret < 0) {
dev_warn(info->dev, "cannot handle is interrupt:%d\n",
irq_type);
@@ -565,6 +678,7 @@ static void sm5502_init_dev_type(struct sm5502_muic_info *info)
static int sm5022_muic_i2c_probe(struct i2c_client *i2c)
{
struct device_node *np = i2c->dev.of_node;
+ const struct regmap_irq_chip *irq_chip;
struct sm5502_muic_info *info;
int i, ret, irq_flags;
@@ -579,10 +693,26 @@ static int sm5022_muic_i2c_probe(struct i2c_client *i2c)
info->dev = &i2c->dev;
info->i2c = i2c;
info->irq = i2c->irq;
- info->muic_irqs = sm5502_muic_irqs;
- info->num_muic_irqs = ARRAY_SIZE(sm5502_muic_irqs);
- info->reg_data = sm5502_reg_data;
- info->num_reg_data = ARRAY_SIZE(sm5502_reg_data);
+ info->type = (uintptr_t)device_get_match_data(info->dev);
+
+ switch (info->type) {
+ case TYPE_SM5502:
+ irq_chip = &sm5502_muic_irq_chip;
+ info->muic_irqs = sm5502_muic_irqs;
+ info->num_muic_irqs = ARRAY_SIZE(sm5502_muic_irqs);
+ info->reg_data = sm5502_reg_data;
+ info->num_reg_data = ARRAY_SIZE(sm5502_reg_data);
+ break;
+ case TYPE_SM5504:
+ irq_chip = &sm5504_muic_irq_chip;
+ info->muic_irqs = sm5504_muic_irqs;
+ info->num_muic_irqs = ARRAY_SIZE(sm5504_muic_irqs);
+ info->reg_data = sm5504_reg_data;
+ info->num_reg_data = ARRAY_SIZE(sm5504_reg_data);
+ break;
+ default:
+ return -EINVAL;
+ }
mutex_init(&info->mutex);
@@ -598,8 +728,8 @@ static int sm5022_muic_i2c_probe(struct i2c_client *i2c)
/* Support irq domain for SM5502 MUIC device */
irq_flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT | IRQF_SHARED;
- ret = devm_regmap_add_irq_chip(info->dev, info->regmap, info->irq, irq_flags,
- 0, &sm5502_muic_irq_chip, &info->irq_data);
+ ret = devm_regmap_add_irq_chip(info->dev, info->regmap, info->irq,
+ irq_flags, 0, irq_chip, &info->irq_data);
if (ret != 0) {
dev_err(info->dev, "failed to request IRQ %d: %d\n",
info->irq, ret);
@@ -660,7 +790,8 @@ static int sm5022_muic_i2c_probe(struct i2c_client *i2c)
}
static const struct of_device_id sm5502_dt_match[] = {
- { .compatible = "siliconmitus,sm5502-muic" },
+ { .compatible = "siliconmitus,sm5502-muic", .data = (void *)TYPE_SM5502 },
+ { .compatible = "siliconmitus,sm5504-muic", .data = (void *)TYPE_SM5504 },
{ },
};
MODULE_DEVICE_TABLE(of, sm5502_dt_match);
@@ -692,6 +823,7 @@ static SIMPLE_DEV_PM_OPS(sm5502_muic_pm_ops,
static const struct i2c_device_id sm5502_i2c_id[] = {
{ "sm5502", TYPE_SM5502 },
+ { "sm5504", TYPE_SM5504 },
{ }
};
MODULE_DEVICE_TABLE(i2c, sm5502_i2c_id);
diff --git a/drivers/extcon/extcon-sm5502.h b/drivers/extcon/extcon-sm5502.h
index ce1f1ec310c4..0ce00274ed86 100644
--- a/drivers/extcon/extcon-sm5502.h
+++ b/drivers/extcon/extcon-sm5502.h
@@ -10,6 +10,7 @@
enum sm5502_types {
TYPE_SM5502,
+ TYPE_SM5504,
};
/* SM5502 registers */
@@ -93,6 +94,13 @@ enum sm5502_reg {
#define SM5502_REG_CONTROL_RAW_DATA_MASK (0x1 << SM5502_REG_CONTROL_RAW_DATA_SHIFT)
#define SM5502_REG_CONTROL_SW_OPEN_MASK (0x1 << SM5502_REG_CONTROL_SW_OPEN_SHIFT)
+#define SM5504_REG_CONTROL_CHGTYP_SHIFT 5
+#define SM5504_REG_CONTROL_USBCHDEN_SHIFT 6
+#define SM5504_REG_CONTROL_ADC_EN_SHIFT 7
+#define SM5504_REG_CONTROL_CHGTYP_MASK (0x1 << SM5504_REG_CONTROL_CHGTYP_SHIFT)
+#define SM5504_REG_CONTROL_USBCHDEN_MASK (0x1 << SM5504_REG_CONTROL_USBCHDEN_SHIFT)
+#define SM5504_REG_CONTROL_ADC_EN_MASK (0x1 << SM5504_REG_CONTROL_ADC_EN_SHIFT)
+
#define SM5502_REG_INTM1_ATTACH_SHIFT 0
#define SM5502_REG_INTM1_DETACH_SHIFT 1
#define SM5502_REG_INTM1_KP_SHIFT 2
@@ -123,6 +131,36 @@ enum sm5502_reg {
#define SM5502_REG_INTM2_STUCK_KEY_RCV_MASK (0x1 << SM5502_REG_INTM2_STUCK_KEY_RCV_SHIFT)
#define SM5502_REG_INTM2_MHL_MASK (0x1 << SM5502_REG_INTM2_MHL_SHIFT)
+#define SM5504_REG_INTM1_ATTACH_SHIFT 0
+#define SM5504_REG_INTM1_DETACH_SHIFT 1
+#define SM5504_REG_INTM1_CHG_DET_SHIFT 2
+#define SM5504_REG_INTM1_DCD_OUT_SHIFT 3
+#define SM5504_REG_INTM1_OVP_EVENT_SHIFT 4
+#define SM5504_REG_INTM1_CONNECT_SHIFT 5
+#define SM5504_REG_INTM1_ADC_CHG_SHIFT 6
+#define SM5504_REG_INTM1_ATTACH_MASK (0x1 << SM5504_REG_INTM1_ATTACH_SHIFT)
+#define SM5504_REG_INTM1_DETACH_MASK (0x1 << SM5504_REG_INTM1_DETACH_SHIFT)
+#define SM5504_REG_INTM1_CHG_DET_MASK (0x1 << SM5504_REG_INTM1_CHG_DET_SHIFT)
+#define SM5504_REG_INTM1_DCD_OUT_MASK (0x1 << SM5504_REG_INTM1_DCD_OUT_SHIFT)
+#define SM5504_REG_INTM1_OVP_EVENT_MASK (0x1 << SM5504_REG_INTM1_OVP_EVENT_SHIFT)
+#define SM5504_REG_INTM1_CONNECT_MASK (0x1 << SM5504_REG_INTM1_CONNECT_SHIFT)
+#define SM5504_REG_INTM1_ADC_CHG_MASK (0x1 << SM5504_REG_INTM1_ADC_CHG_SHIFT)
+
+#define SM5504_REG_INTM2_RID_CHG_SHIFT 0
+#define SM5504_REG_INTM2_UVLO_SHIFT 1
+#define SM5504_REG_INTM2_POR_SHIFT 2
+#define SM5504_REG_INTM2_OVP_FET_SHIFT 4
+#define SM5504_REG_INTM2_OCP_LATCH_SHIFT 5
+#define SM5504_REG_INTM2_OCP_EVENT_SHIFT 6
+#define SM5504_REG_INTM2_OVP_OCP_EVENT_SHIFT 7
+#define SM5504_REG_INTM2_RID_CHG_MASK (0x1 << SM5504_REG_INTM2_RID_CHG_SHIFT)
+#define SM5504_REG_INTM2_UVLO_MASK (0x1 << SM5504_REG_INTM2_UVLO_SHIFT)
+#define SM5504_REG_INTM2_POR_MASK (0x1 << SM5504_REG_INTM2_POR_SHIFT)
+#define SM5504_REG_INTM2_OVP_FET_MASK (0x1 << SM5504_REG_INTM2_OVP_FET_SHIFT)
+#define SM5504_REG_INTM2_OCP_LATCH_MASK (0x1 << SM5504_REG_INTM2_OCP_LATCH_SHIFT)
+#define SM5504_REG_INTM2_OCP_EVENT_MASK (0x1 << SM5504_REG_INTM2_OCP_EVENT_SHIFT)
+#define SM5504_REG_INTM2_OVP_OCP_EVENT_MASK (0x1 << SM5504_REG_INTM2_OVP_OCP_EVENT_SHIFT)
+
#define SM5502_REG_ADC_SHIFT 0
#define SM5502_REG_ADC_MASK (0x1f << SM5502_REG_ADC_SHIFT)
@@ -199,6 +237,9 @@ enum sm5502_reg {
#define SM5502_REG_DEV_TYPE1_DEDICATED_CHG_MASK (0x1 << SM5502_REG_DEV_TYPE1_DEDICATED_CHG_SHIFT)
#define SM5502_REG_DEV_TYPE1_USB_OTG_MASK (0x1 << SM5502_REG_DEV_TYPE1_USB_OTG_SHIFT)
+#define SM5504_REG_DEV_TYPE1_USB_OTG_SHIFT 0
+#define SM5504_REG_DEV_TYPE1_USB_OTG_MASK (0x1 << SM5504_REG_DEV_TYPE1_USB_OTG_SHIFT)
+
#define SM5502_REG_DEV_TYPE2_JIG_USB_ON_SHIFT 0
#define SM5502_REG_DEV_TYPE2_JIG_USB_OFF_SHIFT 1
#define SM5502_REG_DEV_TYPE2_JIG_UART_ON_SHIFT 2
@@ -277,4 +318,42 @@ enum sm5502_irq {
#define SM5502_IRQ_INT2_STUCK_KEY_RCV_MASK BIT(4)
#define SM5502_IRQ_INT2_MHL_MASK BIT(5)
+/* SM5504 Interrupts */
+enum sm5504_irq {
+ /* INT1 */
+ SM5504_IRQ_INT1_ATTACH,
+ SM5504_IRQ_INT1_DETACH,
+ SM5504_IRQ_INT1_CHG_DET,
+ SM5504_IRQ_INT1_DCD_OUT,
+ SM5504_IRQ_INT1_OVP_EVENT,
+ SM5504_IRQ_INT1_CONNECT,
+ SM5504_IRQ_INT1_ADC_CHG,
+
+ /* INT2 */
+ SM5504_IRQ_INT2_RID_CHG,
+ SM5504_IRQ_INT2_UVLO,
+ SM5504_IRQ_INT2_POR,
+ SM5504_IRQ_INT2_OVP_FET,
+ SM5504_IRQ_INT2_OCP_LATCH,
+ SM5504_IRQ_INT2_OCP_EVENT,
+ SM5504_IRQ_INT2_OVP_OCP_EVENT,
+
+ SM5504_IRQ_NUM,
+};
+
+#define SM5504_IRQ_INT1_ATTACH_MASK BIT(0)
+#define SM5504_IRQ_INT1_DETACH_MASK BIT(1)
+#define SM5504_IRQ_INT1_CHG_DET_MASK BIT(2)
+#define SM5504_IRQ_INT1_DCD_OUT_MASK BIT(3)
+#define SM5504_IRQ_INT1_OVP_MASK BIT(4)
+#define SM5504_IRQ_INT1_CONNECT_MASK BIT(5)
+#define SM5504_IRQ_INT1_ADC_CHG_MASK BIT(6)
+#define SM5504_IRQ_INT2_RID_CHG_MASK BIT(0)
+#define SM5504_IRQ_INT2_UVLO_MASK BIT(1)
+#define SM5504_IRQ_INT2_POR_MASK BIT(2)
+#define SM5504_IRQ_INT2_OVP_FET_MASK BIT(4)
+#define SM5504_IRQ_INT2_OCP_LATCH_MASK BIT(5)
+#define SM5504_IRQ_INT2_OCP_EVENT_MASK BIT(6)
+#define SM5504_IRQ_INT2_OVP_OCP_EVENT_MASK BIT(7)
+
#endif /* __LINUX_EXTCON_SM5502_H */
--
2.31.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v2 6/6] extcon: sm5502: Add support for SM5504
2021-05-31 13:34 ` [PATCH v2 6/6] extcon: sm5502: Add support for SM5504 Stephan Gerhold
@ 2021-06-01 16:27 ` Chanwoo Choi
0 siblings, 0 replies; 10+ messages in thread
From: Chanwoo Choi @ 2021-06-01 16:27 UTC (permalink / raw)
To: Stephan Gerhold, Chanwoo Choi, MyungJoo Ham
Cc: Rob Herring, devicetree, linux-kernel, Nikita Travkin,
~postmarketos/upstreaming
Hi,
Almost looks good to me. I add some comments.
On 21. 5. 31. 오후 10:34, Stephan Gerhold wrote:
> SM5504 is another MUIC from Silicon Mitus that is fairly similar
> to SM5502. They seem to use the same register set, but:
>
> - SM5504 has some additional bits in SM5502_REG_CONTROL
> - SM5504 has a quite different set of interrupts
> - SM5504 reports USB OTG as dev_type1 = BIT(0) instead of BIT(7)
>
> Overall it's minor and we can support this using the existing
> enum sm5502_types plus a few switch/if statements.
>
> Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
> ---
> Changes in v2: Fix warning: cast to smaller integer type 'enum sm5502_types'
> from 'const void *' [-Wvoid-pointer-to-enum-cast]
> reported by kernel test robot
>
> Interestingly enough the register set (and especially the interrupts)
> also look *very* similar to Richtek RT8973A (extcon-rt8973a) but
> I didn't investigate this further.
>
> Note that the changes in this patch are mostly based on guesswork
> based on a SM5504 driver from Nitin Chaudhary [1] used in some Samsung
> vendor kernels, since I was not able to find a public datasheet for SM5504.
>
> [1]: https://github.com/NitinChaudharyUSC/MSM8x16_8x26/blob/master/drivers/misc/sm5504.c
> ---
> drivers/extcon/Kconfig | 2 +-
> drivers/extcon/extcon-sm5502.c | 164 +++++++++++++++++++++++++++++----
> drivers/extcon/extcon-sm5502.h | 79 ++++++++++++++++
> 3 files changed, 228 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig
> index e3db936becfd..c69d40ae5619 100644
> --- a/drivers/extcon/Kconfig
> +++ b/drivers/extcon/Kconfig
> @@ -154,7 +154,7 @@ config EXTCON_RT8973A
> from abnormal high input voltage (up to 28V).
>
> config EXTCON_SM5502
> - tristate "Silicon Mitus SM5502 EXTCON support"
> + tristate "Silicon Mitus SM5502/SM5504 EXTCON support"
> depends on I2C
> select IRQ_DOMAIN
> select REGMAP_I2C
> diff --git a/drivers/extcon/extcon-sm5502.c b/drivers/extcon/extcon-sm5502.c
> index 9f40bb9f1f81..49a35db61112 100644
> --- a/drivers/extcon/extcon-sm5502.c
> +++ b/drivers/extcon/extcon-sm5502.c
> @@ -40,6 +40,7 @@ struct sm5502_muic_info {
> struct i2c_client *i2c;
> struct regmap *regmap;
>
> + enum sm5502_types type;
> struct regmap_irq_chip_data *irq_data;
> struct muic_irq *muic_irqs;
> unsigned int num_muic_irqs;
> @@ -90,6 +91,33 @@ static struct reg_data sm5502_reg_data[] = {
> },
> };
>
> +/* Default value of SM5504 register to bring up MUIC device. */
> +static struct reg_data sm5504_reg_data[] = {
> + {
> + .reg = SM5502_REG_RESET,
> + .val = SM5502_REG_RESET_MASK,
> + .invert = true,
> + }, {
> + .reg = SM5502_REG_INTMASK1,
> + .val = SM5504_REG_INTM1_ATTACH_MASK
> + | SM5504_REG_INTM1_DETACH_MASK,
> + .invert = false,
> + }, {
> + .reg = SM5502_REG_INTMASK2,
> + .val = SM5504_REG_INTM2_RID_CHG_MASK
> + | SM5504_REG_INTM2_UVLO_MASK
> + | SM5504_REG_INTM2_POR_MASK,
> + .invert = true,
> + }, {
> + .reg = SM5502_REG_CONTROL,
> + .val = SM5502_REG_CONTROL_MANUAL_SW_MASK
> + | SM5504_REG_CONTROL_CHGTYP_MASK
> + | SM5504_REG_CONTROL_USBCHDEN_MASK
> + | SM5504_REG_CONTROL_ADC_EN_MASK,
> + .invert = true,
> + },
> +};
> +
> /* List of detectable cables */
> static const unsigned int sm5502_extcon_cable[] = {
> EXTCON_USB,
> @@ -198,6 +226,55 @@ static const struct regmap_irq_chip sm5502_muic_irq_chip = {
> .num_irqs = ARRAY_SIZE(sm5502_irqs),
> };
>
> +/* List of supported interrupt for SM5504 */
> +static struct muic_irq sm5504_muic_irqs[] = {
> + { SM5504_IRQ_INT1_ATTACH, "muic-attach" },
> + { SM5504_IRQ_INT1_DETACH, "muic-detach" },
> + { SM5504_IRQ_INT1_CHG_DET, "muic-chg-det" },
> + { SM5504_IRQ_INT1_DCD_OUT, "muic-dcd-out" },
> + { SM5504_IRQ_INT1_OVP_EVENT, "muic-ovp-event" },
> + { SM5504_IRQ_INT1_CONNECT, "muic-connect" },
> + { SM5504_IRQ_INT1_ADC_CHG, "muic-adc-chg" },
> + { SM5504_IRQ_INT2_RID_CHG, "muic-rid-chg" },
> + { SM5504_IRQ_INT2_UVLO, "muic-uvlo" },
> + { SM5504_IRQ_INT2_POR, "muic-por" },
> + { SM5504_IRQ_INT2_OVP_FET, "muic-ovp-fet" },
> + { SM5504_IRQ_INT2_OCP_LATCH, "muic-ocp-latch" },
> + { SM5504_IRQ_INT2_OCP_EVENT, "muic-ocp-event" },
> + { SM5504_IRQ_INT2_OVP_OCP_EVENT, "muic-ovp-ocp-event" },
> +};
> +
> +/* Define interrupt list of SM5504 to register regmap_irq */
> +static const struct regmap_irq sm5504_irqs[] = {
> + /* INT1 interrupts */
> + { .reg_offset = 0, .mask = SM5504_IRQ_INT1_ATTACH_MASK, },
> + { .reg_offset = 0, .mask = SM5504_IRQ_INT1_DETACH_MASK, },
> + { .reg_offset = 0, .mask = SM5504_IRQ_INT1_CHG_DET_MASK, },
> + { .reg_offset = 0, .mask = SM5504_IRQ_INT1_DCD_OUT_MASK, },
> + { .reg_offset = 0, .mask = SM5504_IRQ_INT1_OVP_MASK, },
> + { .reg_offset = 0, .mask = SM5504_IRQ_INT1_CONNECT_MASK, },
> + { .reg_offset = 0, .mask = SM5504_IRQ_INT1_ADC_CHG_MASK, },
> +
> + /* INT2 interrupts */
> + { .reg_offset = 1, .mask = SM5504_IRQ_INT2_RID_CHG_MASK,},
> + { .reg_offset = 1, .mask = SM5504_IRQ_INT2_UVLO_MASK, },
> + { .reg_offset = 1, .mask = SM5504_IRQ_INT2_POR_MASK, },
> + { .reg_offset = 1, .mask = SM5504_IRQ_INT2_OVP_FET_MASK, },
> + { .reg_offset = 1, .mask = SM5504_IRQ_INT2_OCP_LATCH_MASK, },
> + { .reg_offset = 1, .mask = SM5504_IRQ_INT2_OCP_EVENT_MASK, },
> + { .reg_offset = 1, .mask = SM5504_IRQ_INT2_OVP_OCP_EVENT_MASK, },
> +};
> +
> +static const struct regmap_irq_chip sm5504_muic_irq_chip = {
> + .name = "sm5504",
> + .status_base = SM5502_REG_INT1,
> + .mask_base = SM5502_REG_INTMASK1,
> + .mask_invert = false,
> + .num_regs = 2,
> + .irqs = sm5504_irqs,
> + .num_irqs = ARRAY_SIZE(sm5504_irqs),
> +};
> +
> /* Define regmap configuration of SM5502 for I2C communication */
> static bool sm5502_muic_volatile_reg(struct device *dev, unsigned int reg)
> {
> @@ -276,9 +353,14 @@ static int sm5502_muic_set_path(struct sm5502_muic_info *info,
> /* Return cable type of attached or detached accessories */
> static unsigned int sm5502_muic_get_cable_type(struct sm5502_muic_info *info)
> {
> - unsigned int cable_type, adc, dev_type1;
> + unsigned int cable_type, adc, dev_type1, otg_dev_type1;
> int ret;
>
> + if (info->type == TYPE_SM5504)
> + otg_dev_type1 = SM5504_REG_DEV_TYPE1_USB_OTG_MASK;
> + else
> + otg_dev_type1 = SM5502_REG_DEV_TYPE1_USB_OTG_MASK;
Instead of initializing the local variable in this function,
you better to add 'dev_type1' variable in struct sm5502_muic_info.
And then use 'info->dev_type1'.
> +
> /* Read ADC value according to external cable or button */
> ret = regmap_read(info->regmap, SM5502_REG_ADC, &adc);
> if (ret) {
> @@ -301,11 +383,9 @@ static unsigned int sm5502_muic_get_cable_type(struct sm5502_muic_info *info)
> return ret;
> }
>
> - switch (dev_type1) {
> - case SM5502_REG_DEV_TYPE1_USB_OTG_MASK:
> + if (dev_type1 == otg_dev_type1) {
> cable_type = SM5502_MUIC_ADC_GROUND_USB_OTG;
> - break;
> - default:
> + } else {
> dev_dbg(info->dev,
> "cannot identify the cable type: adc(0x%x), dev_type1(0x%x)\n",
> adc, dev_type1);
> @@ -358,6 +438,11 @@ static unsigned int sm5502_muic_get_cable_type(struct sm5502_muic_info *info)
> return ret;
> }
>
> + if (dev_type1 == otg_dev_type1) {
> + cable_type = SM5502_MUIC_ADC_OPEN_USB_OTG;
> + break;
> + }
> +
> switch (dev_type1) {
> case SM5502_REG_DEV_TYPE1_USB_SDP_MASK:
> cable_type = SM5502_MUIC_ADC_OPEN_USB;
> @@ -365,9 +450,6 @@ static unsigned int sm5502_muic_get_cable_type(struct sm5502_muic_info *info)
> case SM5502_REG_DEV_TYPE1_DEDICATED_CHG_MASK:
> cable_type = SM5502_MUIC_ADC_OPEN_TA;
> break;
> - case SM5502_REG_DEV_TYPE1_USB_OTG_MASK:
> - cable_type = SM5502_MUIC_ADC_OPEN_USB_OTG;
> - break;
> default:
> dev_dbg(info->dev,
> "cannot identify the cable type: adc(0x%x)\n",
> @@ -497,6 +579,34 @@ static int sm5502_parse_irq(struct sm5502_muic_info *info, int irq_type)
> return 0;
> }
>
> +static int sm5504_parse_irq(struct sm5502_muic_info *info, int irq_type)
> +{
> + switch (irq_type) {
> + case SM5504_IRQ_INT1_ATTACH:
> + info->irq_attach = true;
> + break;
> + case SM5504_IRQ_INT1_DETACH:
> + info->irq_detach = true;
> + break;
> + case SM5504_IRQ_INT1_CHG_DET:
> + case SM5504_IRQ_INT1_DCD_OUT:
> + case SM5504_IRQ_INT1_OVP_EVENT:
> + case SM5504_IRQ_INT1_CONNECT:
> + case SM5504_IRQ_INT1_ADC_CHG:
> + case SM5504_IRQ_INT2_RID_CHG:
> + case SM5504_IRQ_INT2_UVLO:
> + case SM5504_IRQ_INT2_POR:
> + case SM5504_IRQ_INT2_OVP_FET:
> + case SM5504_IRQ_INT2_OCP_LATCH:
> + case SM5504_IRQ_INT2_OCP_EVENT:
> + case SM5504_IRQ_INT2_OVP_OCP_EVENT:
> + default:
> + break;
> + }
> +
> + return 0;
> +}
> +
> static irqreturn_t sm5502_muic_irq_handler(int irq, void *data)
> {
> struct sm5502_muic_info *info = data;
> @@ -506,7 +616,10 @@ static irqreturn_t sm5502_muic_irq_handler(int irq, void *data)
> if (irq == info->muic_irqs[i].virq)
> irq_type = info->muic_irqs[i].irq;
>
> - ret = sm5502_parse_irq(info, irq_type);
> + if (info->type == TYPE_SM5504)
> + ret = sm5504_parse_irq(info, irq_type);
> + else
> + ret = sm5502_parse_irq(info, irq_type);
ditto. Better to add 'parse_irq' function pointer into struct
sm5502_muic_info. And use 'info->parse_irq' instead of this.
> if (ret < 0) {
> dev_warn(info->dev, "cannot handle is interrupt:%d\n",
> irq_type);
> @@ -565,6 +678,7 @@ static void sm5502_init_dev_type(struct sm5502_muic_info *info)
> static int sm5022_muic_i2c_probe(struct i2c_client *i2c)
> {
> struct device_node *np = i2c->dev.of_node;
> + const struct regmap_irq_chip *irq_chip;
> struct sm5502_muic_info *info;
> int i, ret, irq_flags;
>
> @@ -579,10 +693,26 @@ static int sm5022_muic_i2c_probe(struct i2c_client *i2c)
> info->dev = &i2c->dev;
> info->i2c = i2c;
> info->irq = i2c->irq;
> - info->muic_irqs = sm5502_muic_irqs;
> - info->num_muic_irqs = ARRAY_SIZE(sm5502_muic_irqs);
> - info->reg_data = sm5502_reg_data;
> - info->num_reg_data = ARRAY_SIZE(sm5502_reg_data);
> + info->type = (uintptr_t)device_get_match_data(info->dev);
> +
> + switch (info->type) {
> + case TYPE_SM5502:
> + irq_chip = &sm5502_muic_irq_chip;
> + info->muic_irqs = sm5502_muic_irqs;
> + info->num_muic_irqs = ARRAY_SIZE(sm5502_muic_irqs);
> + info->reg_data = sm5502_reg_data;
> + info->num_reg_data = ARRAY_SIZE(sm5502_reg_data);
> + break;
> + case TYPE_SM5504:
> + irq_chip = &sm5504_muic_irq_chip;
> + info->muic_irqs = sm5504_muic_irqs;
> + info->num_muic_irqs = ARRAY_SIZE(sm5504_muic_irqs);
> + info->reg_data = sm5504_reg_data;
> + info->num_reg_data = ARRAY_SIZE(sm5504_reg_data);
> + break;
> + default:
> + return -EINVAL;
> + }
>
> mutex_init(&info->mutex);
>
> @@ -598,8 +728,8 @@ static int sm5022_muic_i2c_probe(struct i2c_client *i2c)
>
> /* Support irq domain for SM5502 MUIC device */
> irq_flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT | IRQF_SHARED;
> - ret = devm_regmap_add_irq_chip(info->dev, info->regmap, info->irq, irq_flags,
> - 0, &sm5502_muic_irq_chip, &info->irq_data);
> + ret = devm_regmap_add_irq_chip(info->dev, info->regmap, info->irq,
> + irq_flags, 0, irq_chip, &info->irq_data);
> if (ret != 0) {
> dev_err(info->dev, "failed to request IRQ %d: %d\n",
> info->irq, ret);
> @@ -660,7 +790,8 @@ static int sm5022_muic_i2c_probe(struct i2c_client *i2c)
> }
>
> static const struct of_device_id sm5502_dt_match[] = {
> - { .compatible = "siliconmitus,sm5502-muic" },
> + { .compatible = "siliconmitus,sm5502-muic", .data = (void *)TYPE_SM5502 },
> + { .compatible = "siliconmitus,sm5504-muic", .data = (void *)TYPE_SM5504 },
> { },
> };
> MODULE_DEVICE_TABLE(of, sm5502_dt_match);
> @@ -692,6 +823,7 @@ static SIMPLE_DEV_PM_OPS(sm5502_muic_pm_ops,
>
> static const struct i2c_device_id sm5502_i2c_id[] = {
> { "sm5502", TYPE_SM5502 },
> + { "sm5504", TYPE_SM5504 },
> { }
> };
> MODULE_DEVICE_TABLE(i2c, sm5502_i2c_id);
> diff --git a/drivers/extcon/extcon-sm5502.h b/drivers/extcon/extcon-sm5502.h
> index ce1f1ec310c4..0ce00274ed86 100644
> --- a/drivers/extcon/extcon-sm5502.h
> +++ b/drivers/extcon/extcon-sm5502.h
> @@ -10,6 +10,7 @@
>
> enum sm5502_types {
> TYPE_SM5502,
> + TYPE_SM5504,
> };
>
> /* SM5502 registers */
> @@ -93,6 +94,13 @@ enum sm5502_reg {
> #define SM5502_REG_CONTROL_RAW_DATA_MASK (0x1 << SM5502_REG_CONTROL_RAW_DATA_SHIFT)
> #define SM5502_REG_CONTROL_SW_OPEN_MASK (0x1 << SM5502_REG_CONTROL_SW_OPEN_SHIFT)
>
> +#define SM5504_REG_CONTROL_CHGTYP_SHIFT 5
> +#define SM5504_REG_CONTROL_USBCHDEN_SHIFT 6
> +#define SM5504_REG_CONTROL_ADC_EN_SHIFT 7
> +#define SM5504_REG_CONTROL_CHGTYP_MASK (0x1 << SM5504_REG_CONTROL_CHGTYP_SHIFT)
> +#define SM5504_REG_CONTROL_USBCHDEN_MASK (0x1 << SM5504_REG_CONTROL_USBCHDEN_SHIFT)
> +#define SM5504_REG_CONTROL_ADC_EN_MASK (0x1 << SM5504_REG_CONTROL_ADC_EN_SHIFT)
> +
> #define SM5502_REG_INTM1_ATTACH_SHIFT 0
> #define SM5502_REG_INTM1_DETACH_SHIFT 1
> #define SM5502_REG_INTM1_KP_SHIFT 2
> @@ -123,6 +131,36 @@ enum sm5502_reg {
> #define SM5502_REG_INTM2_STUCK_KEY_RCV_MASK (0x1 << SM5502_REG_INTM2_STUCK_KEY_RCV_SHIFT)
> #define SM5502_REG_INTM2_MHL_MASK (0x1 << SM5502_REG_INTM2_MHL_SHIFT)
>
> +#define SM5504_REG_INTM1_ATTACH_SHIFT 0
> +#define SM5504_REG_INTM1_DETACH_SHIFT 1
> +#define SM5504_REG_INTM1_CHG_DET_SHIFT 2
> +#define SM5504_REG_INTM1_DCD_OUT_SHIFT 3
> +#define SM5504_REG_INTM1_OVP_EVENT_SHIFT 4
> +#define SM5504_REG_INTM1_CONNECT_SHIFT 5
> +#define SM5504_REG_INTM1_ADC_CHG_SHIFT 6
> +#define SM5504_REG_INTM1_ATTACH_MASK (0x1 << SM5504_REG_INTM1_ATTACH_SHIFT)
> +#define SM5504_REG_INTM1_DETACH_MASK (0x1 << SM5504_REG_INTM1_DETACH_SHIFT)
> +#define SM5504_REG_INTM1_CHG_DET_MASK (0x1 << SM5504_REG_INTM1_CHG_DET_SHIFT)
> +#define SM5504_REG_INTM1_DCD_OUT_MASK (0x1 << SM5504_REG_INTM1_DCD_OUT_SHIFT)
> +#define SM5504_REG_INTM1_OVP_EVENT_MASK (0x1 << SM5504_REG_INTM1_OVP_EVENT_SHIFT)
> +#define SM5504_REG_INTM1_CONNECT_MASK (0x1 << SM5504_REG_INTM1_CONNECT_SHIFT)
> +#define SM5504_REG_INTM1_ADC_CHG_MASK (0x1 << SM5504_REG_INTM1_ADC_CHG_SHIFT)
> +
> +#define SM5504_REG_INTM2_RID_CHG_SHIFT 0
> +#define SM5504_REG_INTM2_UVLO_SHIFT 1
> +#define SM5504_REG_INTM2_POR_SHIFT 2
> +#define SM5504_REG_INTM2_OVP_FET_SHIFT 4
> +#define SM5504_REG_INTM2_OCP_LATCH_SHIFT 5
> +#define SM5504_REG_INTM2_OCP_EVENT_SHIFT 6
> +#define SM5504_REG_INTM2_OVP_OCP_EVENT_SHIFT 7
> +#define SM5504_REG_INTM2_RID_CHG_MASK (0x1 << SM5504_REG_INTM2_RID_CHG_SHIFT)
> +#define SM5504_REG_INTM2_UVLO_MASK (0x1 << SM5504_REG_INTM2_UVLO_SHIFT)
> +#define SM5504_REG_INTM2_POR_MASK (0x1 << SM5504_REG_INTM2_POR_SHIFT)
> +#define SM5504_REG_INTM2_OVP_FET_MASK (0x1 << SM5504_REG_INTM2_OVP_FET_SHIFT)
> +#define SM5504_REG_INTM2_OCP_LATCH_MASK (0x1 << SM5504_REG_INTM2_OCP_LATCH_SHIFT)
> +#define SM5504_REG_INTM2_OCP_EVENT_MASK (0x1 << SM5504_REG_INTM2_OCP_EVENT_SHIFT)
> +#define SM5504_REG_INTM2_OVP_OCP_EVENT_MASK (0x1 << SM5504_REG_INTM2_OVP_OCP_EVENT_SHIFT)
> +
> #define SM5502_REG_ADC_SHIFT 0
> #define SM5502_REG_ADC_MASK (0x1f << SM5502_REG_ADC_SHIFT)
>
> @@ -199,6 +237,9 @@ enum sm5502_reg {
> #define SM5502_REG_DEV_TYPE1_DEDICATED_CHG_MASK (0x1 << SM5502_REG_DEV_TYPE1_DEDICATED_CHG_SHIFT)
> #define SM5502_REG_DEV_TYPE1_USB_OTG_MASK (0x1 << SM5502_REG_DEV_TYPE1_USB_OTG_SHIFT)
>
> +#define SM5504_REG_DEV_TYPE1_USB_OTG_SHIFT 0
> +#define SM5504_REG_DEV_TYPE1_USB_OTG_MASK (0x1 << SM5504_REG_DEV_TYPE1_USB_OTG_SHIFT)
> +
> #define SM5502_REG_DEV_TYPE2_JIG_USB_ON_SHIFT 0
> #define SM5502_REG_DEV_TYPE2_JIG_USB_OFF_SHIFT 1
> #define SM5502_REG_DEV_TYPE2_JIG_UART_ON_SHIFT 2
> @@ -277,4 +318,42 @@ enum sm5502_irq {
> #define SM5502_IRQ_INT2_STUCK_KEY_RCV_MASK BIT(4)
> #define SM5502_IRQ_INT2_MHL_MASK BIT(5)
>
> +/* SM5504 Interrupts */
> +enum sm5504_irq {
> + /* INT1 */
> + SM5504_IRQ_INT1_ATTACH,
> + SM5504_IRQ_INT1_DETACH,
> + SM5504_IRQ_INT1_CHG_DET,
> + SM5504_IRQ_INT1_DCD_OUT,
> + SM5504_IRQ_INT1_OVP_EVENT,
> + SM5504_IRQ_INT1_CONNECT,
> + SM5504_IRQ_INT1_ADC_CHG,
> +
> + /* INT2 */
> + SM5504_IRQ_INT2_RID_CHG,
> + SM5504_IRQ_INT2_UVLO,
> + SM5504_IRQ_INT2_POR,
> + SM5504_IRQ_INT2_OVP_FET,
> + SM5504_IRQ_INT2_OCP_LATCH,
> + SM5504_IRQ_INT2_OCP_EVENT,
> + SM5504_IRQ_INT2_OVP_OCP_EVENT,
> +
> + SM5504_IRQ_NUM,
> +};
> +
> +#define SM5504_IRQ_INT1_ATTACH_MASK BIT(0)
> +#define SM5504_IRQ_INT1_DETACH_MASK BIT(1)
> +#define SM5504_IRQ_INT1_CHG_DET_MASK BIT(2)
> +#define SM5504_IRQ_INT1_DCD_OUT_MASK BIT(3)
> +#define SM5504_IRQ_INT1_OVP_MASK BIT(4)
> +#define SM5504_IRQ_INT1_CONNECT_MASK BIT(5)
> +#define SM5504_IRQ_INT1_ADC_CHG_MASK BIT(6)
> +#define SM5504_IRQ_INT2_RID_CHG_MASK BIT(0)
> +#define SM5504_IRQ_INT2_UVLO_MASK BIT(1)
> +#define SM5504_IRQ_INT2_POR_MASK BIT(2)
> +#define SM5504_IRQ_INT2_OVP_FET_MASK BIT(4)
> +#define SM5504_IRQ_INT2_OCP_LATCH_MASK BIT(5)
> +#define SM5504_IRQ_INT2_OCP_EVENT_MASK BIT(6)
> +#define SM5504_IRQ_INT2_OVP_OCP_EVENT_MASK BIT(7)
> +
> #endif /* __LINUX_EXTCON_SM5502_H */
>
--
Best Regards,
Samsung Electronics
Chanwoo Choi
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2 0/6] extcon: sm5502: Add support for SM5504
2021-05-31 13:34 [PATCH v2 0/6] extcon: sm5502: Add support for SM5504 Stephan Gerhold
` (5 preceding siblings ...)
2021-05-31 13:34 ` [PATCH v2 6/6] extcon: sm5502: Add support for SM5504 Stephan Gerhold
@ 2021-06-01 16:28 ` Chanwoo Choi
6 siblings, 0 replies; 10+ messages in thread
From: Chanwoo Choi @ 2021-06-01 16:28 UTC (permalink / raw)
To: Stephan Gerhold, Chanwoo Choi, MyungJoo Ham
Cc: Rob Herring, devicetree, linux-kernel, Nikita Travkin,
~postmarketos/upstreaming
On 21. 5. 31. 오후 10:34, Stephan Gerhold wrote:
> This patch series adds support for SM5504 to the existing extcon-sm5502
> driver. SM5502 and SM5504 are fairly similar so support for SM5504 can
> be added with a few simple if statements in the code.
>
> I also put a few cleanup patches in front and convert the device tree
> bindings to DT schema.
>
> I tested this patch series on both SM5502 (Samsung Galaxy A5 2015)
> and SM5504 (Samsung Galaxy S4 Mini Value Edition) and it seems to work
> just fine for both.
>
> ---
> Changes in v2: Fix compile warning in last patch
> v1: https://lore.kernel.org/lkml/20210520112334.129556-1-stephan@gerhold.net/
>
> Stephan Gerhold (6):
> extcon: sm5502: Use devm_regmap_add_irq_chip()
> extcon: sm5502: Implement i2c_driver->probe_new()
> extcon: sm5502: Drop invalid register write in sm5502_reg_data
> dt-bindings: extcon: sm5502: Convert to DT schema
> dt-bindings: extcon: sm5502: Document siliconmitus,sm5504-muic
> extcon: sm5502: Add support for SM5504
>
> .../bindings/extcon/extcon-sm5502.txt | 21 --
> .../extcon/siliconmitus,sm5502-muic.yaml | 52 +++++
> drivers/extcon/Kconfig | 2 +-
> drivers/extcon/extcon-sm5502.c | 180 +++++++++++++++---
> drivers/extcon/extcon-sm5502.h | 79 ++++++++
> 5 files changed, 282 insertions(+), 52 deletions(-)
> delete mode 100644 Documentation/devicetree/bindings/extcon/extcon-sm5502.txt
> create mode 100644 Documentation/devicetree/bindings/extcon/siliconmitus,sm5502-muic.yaml
>
Applied patch1-patch3. Thanks.
--
Best Regards,
Samsung Electronics
Chanwoo Choi
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2 4/6] dt-bindings: extcon: sm5502: Convert to DT schema
2021-05-31 13:34 ` [PATCH v2 4/6] dt-bindings: extcon: sm5502: Convert to DT schema Stephan Gerhold
@ 2021-06-02 16:48 ` Rob Herring
0 siblings, 0 replies; 10+ messages in thread
From: Rob Herring @ 2021-06-02 16:48 UTC (permalink / raw)
To: Stephan Gerhold
Cc: Chanwoo Choi, Rob Herring, ~postmarketos/upstreaming, devicetree,
Nikita Travkin, MyungJoo Ham, linux-kernel
On Mon, 31 May 2021 15:34:36 +0200, Stephan Gerhold wrote:
> Convert the extcon-sm5502 device tree bindings to DT schema.
>
> Signed-off-by: Stephan Gerhold <stephan@gerhold.net>
> ---
> .../bindings/extcon/extcon-sm5502.txt | 21 --------
> .../extcon/siliconmitus,sm5502-muic.yaml | 50 +++++++++++++++++++
> 2 files changed, 50 insertions(+), 21 deletions(-)
> delete mode 100644 Documentation/devicetree/bindings/extcon/extcon-sm5502.txt
> create mode 100644 Documentation/devicetree/bindings/extcon/siliconmitus,sm5502-muic.yaml
>
Reviewed-by: Rob Herring <robh@kernel.org>
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2021-06-02 16:48 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-31 13:34 [PATCH v2 0/6] extcon: sm5502: Add support for SM5504 Stephan Gerhold
2021-05-31 13:34 ` [PATCH v2 1/6] extcon: sm5502: Use devm_regmap_add_irq_chip() Stephan Gerhold
2021-05-31 13:34 ` [PATCH v2 2/6] extcon: sm5502: Implement i2c_driver->probe_new() Stephan Gerhold
2021-05-31 13:34 ` [PATCH v2 3/6] extcon: sm5502: Drop invalid register write in sm5502_reg_data Stephan Gerhold
2021-05-31 13:34 ` [PATCH v2 4/6] dt-bindings: extcon: sm5502: Convert to DT schema Stephan Gerhold
2021-06-02 16:48 ` Rob Herring
2021-05-31 13:34 ` [PATCH v2 5/6] dt-bindings: extcon: sm5502: Document siliconmitus,sm5504-muic Stephan Gerhold
2021-05-31 13:34 ` [PATCH v2 6/6] extcon: sm5502: Add support for SM5504 Stephan Gerhold
2021-06-01 16:27 ` Chanwoo Choi
2021-06-01 16:28 ` [PATCH v2 0/6] " Chanwoo Choi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).