i2c: gpio: support write-only sda
cover i2c: gpio: support write-only sda
There are slave devices that understand I2C but have read-only SDA and SCL. Examples are FD650 7-segment LED controller and its derivatives. Typical board designs don't even have a pull-up for both pins. This patch makes i2c-gpio usable with such devices, based on new DT property i2c-gpio,sda-output-only.
Heiner Kallweit (3):
dt-bindings: i2c-gpio: Add property i2c-gpio,sda-output-only
i2c: algo: bit: allow getsda to be NULL
i2c: gpio: support write-only sda
.../devicetree/bindings/i2c/i2c-gpio.yaml | 4 ++++ drivers/i2c/algos/i2c-algo-bit.c | 16 +++++++++++++--- drivers/i2c/busses/i2c-gpio.c | 14 +++++++++++--- include/linux/platform_data/i2c-gpio.h | 2 ++ 4 files changed, 30 insertions(+), 6 deletions(-)
Signature · 1 line
2.35.3
PATCH 1/3 dt-bindings: i2c-gpio: Add property i2c-gpio,sda-output-only
This documents new property i2c-gpio,sda-output-only.
--- Documentation/devicetree/bindings/i2c/i2c-gpio.yaml | 4 ++++ 1 file changed, 4 insertions(+)
Documentation/devicetree/bindings/i2c/i2c-gpio.yaml +4 -0
@@ -33,6 +33,10 @@ properties: open drain. maxItems: 1 + i2c-gpio,sda-output-only: + description: sda as output only + type: boolean + i2c-gpio,scl-output-only: description: scl as output only type: boolean
Signature · 1 line
2.35.3
Rob Herring
maintainerRe: [PATCH 1/3] dt-bindings: i2c-gpio: Add property i2c-gpio,sda-output-only
Quoted 1 line · Heiner Kallweit
This documents new property i2c-gpio,sda-output-only.
The diff tells me that. The commit message needs the same justification(s) as you have in the cover letter or patch 3.
Quoted 26 lines
Signed-off-by Heiner Kallweit <[email protected]>--- Documentation/devicetree/bindings/i2c/i2c-gpio.yaml | 4 ++++ 1 file changed, 4 insertions(+)Documentation/devicetree/bindings/i2c/i2c-gpio.yaml +4
-0@@ -33,6 +33,10 @@ properties: open drain. maxItems: 1 + i2c-gpio,sda-output-only: + description: sda as output only + type: boolean + i2c-gpio,scl-output-only: description: scl as output only type: booleanSignature · 1 line
2.35.3
PATCH 2/3 i2c: algo: bit: allow getsda to be NULL
In reply to Heiner KallweitThis is in preparation of supporting write-only SDA in i2c-gpio.
--- drivers/i2c/algos/i2c-algo-bit.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
drivers/i2c/algos/i2c-algo-bit.c +13 -3
@@ -184,8 +184,9 @@ static int i2c_outb(struct i2c_adapter *i2c_adap, unsigned char c)/* read ack: SDA should be pulled down by slave, or it may * NAK (usually to report problems with the data we wrote). +* Report ACK if SDA is write-only. */ - ack = !getsda (adap);/* ack: sda is pulled low -> success */ + ack = !adap->getsda || !getsda (adap);/* ack: sda is pulled low -> success */ bit_dbg (2 , &i2c_adap->dev,"i2c_outb: 0x%02x %s\n" , (int )c, ack ?"A" :"NA" );
@@ -203,6 +204,9 @@ static int i2c_inb(struct i2c_adapter *i2c_adap)unsigned char indata =0 ;struct i2c_algo_bit_data *adap = i2c_adap->algo_data; +if (!adap->getsda) +return -EOPNOTSUPP ; +/* assert: scl is low */ sdahi (adap);for (i =0 ; i <8 ; i++) {
@@ -232,6 +236,10 @@ static int test_bus(struct i2c_adapter *i2c_adap)const char *name = i2c_adap->name;int scl, sda, ret; +/* Testing not possible if both pins are write-only. */ +if (adap->getscl ==NULL && adap->getsda ==NULL ) +return 0 ; +if (adap->pre_xfer) { ret = adap->pre_xfer (i2c_adap);if (ret <0 )
@@ -670,8 +678,10 @@ static int __i2c_bit_add_bus(struct i2c_adapter *adap,if (ret <0 )return ret; -/* Complain if SCL can't be read */ -if (bit_adap->getscl ==NULL ) { +if (bit_adap->getscl ==NULL && bit_adap->getsda ==NULL ) +dev_info (&adap->dev,"I2C-like interface, SDA and SCL are write-only\n" ); +else if (bit_adap->getscl ==NULL ) { +/* Complain if SCL can't be read */ dev_warn (&adap->dev,"Not I2C compliant: can't read SCL\n" );dev_warn (&adap->dev,"Bus may be unreliable\n" ); }
Signature · 1 line
2.35.3
PATCH 3/3 i2c: gpio: support write-only sda
In reply to Heiner KallweitThere are slave devices that understand I2C but have read-only SDA and SCL. Examples are FD650 7-segment LED controller and its derivatives. Typical board designs don't even have a pull-up for both pins. Therefore don't enforce open-drain if SDA and SCL both are unidirectional. This patch makes i2c-gpio usable with such devices, based on new DT property i2c-gpio,sda-output-only.
--- drivers/i2c/busses/i2c-gpio.c | 14 +++++++++++--- include/linux/platform_data/i2c-gpio.h | 2 ++ 2 files changed, 13 insertions(+), 3 deletions(-)
drivers/i2c/busses/i2c-gpio.c +11 -3
@@ -316,6 +316,8 @@ static void of_i2c_gpio_get_props(struct device_node *np,of_property_read_bool (np,"i2c-gpio,scl-open-drain" ); pdata->scl_is_output_only =of_property_read_bool (np,"i2c-gpio,scl-output-only" ); + pdata->sda_is_output_only = +of_property_read_bool (np,"i2c-gpio,sda-output-only" ); } static struct gpio_desc *i2c_gpio_get_desc(struct device *dev,
@@ -363,6 +365,7 @@ static int i2c_gpio_probe(struct platform_device *pdev)struct device *dev = &pdev->dev;struct device_node *np = dev->of_node;enum gpiod_flags gflags; +bool sda_scl_output_only;int ret; priv =devm_kzalloc (dev,sizeof (*priv),GFP_KERNEL );
@@ -391,8 +394,12 @@ static int i2c_gpio_probe(struct platform_device *pdev)* marking these lines to be handled as open drain, and we should just * handle them as we handle any other output. Else we enforce open * drain as this is required for an I2C bus. +* If SCL/SDA both are write-only, then this indicates I2C-like slaves +* with read-only SCL/SDA. Such slaves don't need open-drain, and partially +* don't even work with open-drain. */ -if (pdata->sda_is_open_drain) + sda_scl_output_only = pdata->sda_is_output_only && pdata->scl_is_output_only; +if (pdata->sda_is_open_drain || sda_scl_output_only) gflags =GPIOD_OUT_HIGH ;else gflags =GPIOD_OUT_HIGH_OPEN_DRAIN ;
@@ -400,7 +407,7 @@ static int i2c_gpio_probe(struct platform_device *pdev)if (IS_ERR (priv->sda))return PTR_ERR (priv->sda); -if (pdata->scl_is_open_drain) +if (pdata->scl_is_open_drain || sda_scl_output_only) gflags =GPIOD_OUT_HIGH ;else gflags =GPIOD_OUT_HIGH_OPEN_DRAIN ;
@@ -418,7 +425,8 @@ static int i2c_gpio_probe(struct platform_device *pdev)if (!pdata->scl_is_output_only) bit_data->getscl = i2c_gpio_getscl; - bit_data->getsda = i2c_gpio_getsda; +if (!pdata->sda_is_output_only) + bit_data->getsda = i2c_gpio_getsda;if (pdata->udelay) bit_data->udelay = pdata->udelay;
include/linux/platform_data/i2c-gpio.h +2 -0
@@ -16,6 +16,7 @@* isn't actively driven high when setting the output value high. * gpio_get_value() must return the actual pin state even if the * pin is configured as an output. +* @sda_is_output_only: I2C-like interface, SDA is write-only. * @scl_is_open_drain: SCL is set up as open drain. Same requirements * as for sda_is_open_drain apply. * @scl_is_output_only: SCL output drivers cannot be turned off.
@@ -24,6 +25,7 @@ struct i2c_gpio_platform_data {int udelay;int timeout; unsigned int sda_is_open_drain:1; + unsigned int sda_is_output_only:1; unsigned int scl_is_open_drain:1; unsigned int scl_is_output_only:1; };
Signature · 1 line
2.35.3