Monday, October 31, 2022

[SOLVED] How to use gpio from device tree in a i2c_driver?

Issue

I've written an I2C driver. I want to make the GPIO which it uses configurable from the device tree.

My device tree entry is currently:

&i2c1 {
    clock-frequency = <100000>;
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_i2c1>;
    status = "okay";
    ...
    myi2c: myi2c@43 {
        compatible = "fsl,myi2c";
        reg = <0x43>;
    };

I'd like to add this line into the myi2c stanza:

        myi2c-gpios = <&gpio4 29 GPIO_ACTIVE_HIGH>;

I can see how to do this, if I was writing a platform driver:

static int gpio_init_probe(struct platform_device *pdev)
{
   int i = 0;

   printk("GPIO example init\n");

   /* "greenled" label is matching the device tree declaration. OUT_LOW is the value at init */
   green = devm_gpiod_get(&pdev->dev, "greenled", GPIOD_OUT_LOW);

but in my driver's i2c_probe(), I have no access to a struct platform_device *:

static int myi2c_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id)

How can I read the value of myi2c-gpios from the device tree and use it in my i2c driver?


Solution

I found this driver to use as an example:

static int sn65dsi84_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
    ...
    struct gpio_desc *enable_gpio;

    enable_gpio = devm_gpiod_get_optional(&client->dev, "enable", GPIOD_OUT_HIGH);
    if (enable_gpio)
        gpiod_set_value_cansleep(enable_gpio, 1);

and its device tree is:

&i2c2 {
    clock-frequency = <100000>;
    pinctrl-names = "default";
    pinctrl-0 = <&pinctrl_i2c2>;
    status = "okay";

    dsi_lvds_bridge: sn65dsi84@2c {
        status = "disabled";
        reg = <0x2c>;
        compatible = "ti,sn65dsi84";
        enable-gpios = <&gpio4 28 GPIO_ACTIVE_HIGH>;

So devm_gpiod_get_optional() seems to be the answer.



Answered By - fadedbee
Answer Checked By - Terry (WPSolving Volunteer)