title: How to write multiple slave i2c client device driver?
body: <p>I am trying to develop a driver for an embedded board. The driver is supposed to open up an interface for <strong>v4l2</strong> and communicate with 2 devices using <strong>i2c</strong>. the driver will act as a master.</p>
  
  <p>I can't seem to understand how <code>i2c_device_id</code> array and <code>i2c_add_driver</code> functions work. I read documentation in kernel source but it won't help me on multiple slave clients.</p>
  
  <ul>
  <li>Do I have to have two seperate probe functions? </li>
  <li>Do i have to call <code>i2c_add_driver</code> two times? </li>
  <li>If not how am I going to be able to save two different clients to be able to send different bytes to different addresses.</li>
  </ul>
  
  <p>I am pasting my code here. I tried to instantiate two <code>i2c_drivers</code>, called <code>i2c_driver_add</code> two times and implemented i2c probe seperately. The code doesn't work telling me that <code>foo1</code>  is already registered when it calls <code>i2c_add_driver</code> for the second time.</p>
  
  <p>I defined two blocks under <code>i2c1</code> in my dts file like:</p>
  
  <pre><code>&amp;i2c1 {
  
  ...
      foo0: foo0@00 {
          compatible = "bar,foo0";
          reg = &lt;0x00&gt;;
          pinctrl-names = "default";
          pinctrl-0 = &lt;&amp;pinctrl_ipu1_2&gt;;
          clocks = &lt;&amp;clks IMX6QDL_CLK_CKO&gt;;
          clock-names = "csi_mclk";
          DOVDD-supply = &lt;&amp;vgen4_reg&gt;; /* 1.8v */
          AVDD-supply = &lt;&amp;vgen3_reg&gt;;  /* 2.8v, on rev C board is VGEN3,
                          on rev B board is VGEN5 */
          DVDD-supply = &lt;&amp;vgen2_reg&gt;;  /* 1.5v*/
          pwn-gpios = &lt;&amp;gpio1 16 1&gt;;   /* active low: SD1_DAT0 */
          rst-gpios = &lt;&amp;gpio1 17 0&gt;;   /* active high: SD1_DAT1 */
          csi_id = &lt;0&gt;;
          mclk = &lt;24000000&gt;;
          mclk_source = &lt;0&gt;;
      };
  
      foo1: foo1@02 {
          compatible = "bar, foo1";
          reg = &lt;0x02&gt;;
          pinctrl-names = "default";
          pinctrl-0 = &lt;&amp;pinctrl_ipu1_2&gt;;
          clocks = &lt;&amp;clks IMX6QDL_CLK_CKO&gt;;
          clock-names = "csi_mclk";
          DOVDD-supply = &lt;&amp;vgen4_reg&gt;; /* 1.8v */
          AVDD-supply = &lt;&amp;vgen3_reg&gt;;  /* 2.8v, on rev C board is VGEN3,
                          on rev B board is VGEN5 */
          DVDD-supply = &lt;&amp;vgen2_reg&gt;;  /* 1.5v*/
          pwn-gpios = &lt;&amp;gpio1 16 1&gt;;   /* active low: SD1_DAT0 */
          rst-gpios = &lt;&amp;gpio1 17 0&gt;;   /* active high: SD1_DAT1 */
          csi_id = &lt;0&gt;;
          mclk = &lt;24000000&gt;;
          mclk_source = &lt;0&gt;;
      };
  
  ...
  </code></pre>
  
  <p>Two blocks are exactly the same except their names.</p>
  
  <p>In the driver file I instantiated following structs:</p>
  
  <pre><code>static const struct i2c_device_id foo_id[] = {
      {"foo0", 0},
      {"foo1", 1},
      {},
  };
  
  static struct i2c_driver foo0_i2c_driver = {
      .driver = {
          .owner = THIS_MODULE,
          .name = "foo0",
      },
      .probe = foo0_probe,
      .remove = foo0_remove,
      .id_table = foo_id,
  };
  
  static struct i2c_driver foo1_i2c_driver = {
      .driver = {
          .owner = THIS_MODULE,
          .name = "foo1",
      },
      .probe = foo1_probe,
      .remove = foo1_remove,
      .id_table = foo_id,
  };
  </code></pre>
  
  <p>Below are my <code>init</code> and <code>exit</code> functions:</p>
  
  <pre><code>MODULE_DEVICE_TABLE(i2c, foo_id);
  
  static __init int foo_init(void)
  {
      u8 err;
  
      err = i2c_add_driver(&amp;foo0_i2c_driver);
      if (err != 0)
          pr_err("%s:driver registration failed i2c-slave0, error=%d\n",
              __func__, err);
  
      err = i2c_add_driver(&amp;foo1_i2c_driver);
      if (err != 0)
          pr_err("%s:driver registration failed i2c-slave1, error=%d\n",
              __func__, err);
  
      return err;
  }
  static void __exit foo_clean(void)
  {
      if((&amp;foo0_i2c_driver) != NULL &amp;&amp; i2c0initialized)
      {
          i2c_del_driver(&amp;foo0_i2c_driver);
          i2c0initialized = 0;
      }
      if((&amp;foo1_i2c_driver) != NULL &amp;&amp; i2c1initialized)
      {
          i2c_del_driver(&amp;foo1_i2c_driver);
          i2c1initialized = 0;
      }
  }
  
  module_init(foo_init);
  module_exit(foo_clean);
  </code></pre>
  
  <p>Below is my <code>probe</code> function. I have two copies for it for both slaves.</p>
  
  <pre><code>static int foo_probe(struct i2c_client *client,
                            const struct i2c_device_id *device_id)
  {
      struct pinctrl *pinctrls;
      struct device *dev = &amp;client-&gt;dev;
  
      int ret = 0;
  
      pinctrls = devm_pinctrl_get_select_default(dev);
      if(IS_ERR(pinctrls))
      {
          dev_err(dev, "pinctrl setup failed\n");
          return PTR_ERR(pinctrls);
      }
  
      memset(&amp;foo_data, 0, sizeof(foo_data));
      foo_data.sensor_clk = devm_clk_get(dev, "csi_mclk");
      if(IS_ERR(foo_data.sensor_clk))
      {
          dev_err(dev, "get mclk failed\n");
          return PTR_ERR(foo_data.sensor_clk);
      }
  
      ret = of_property_read_u32(dev-&gt;of_node, "mclk", &amp;(foo_data.mclk));
      if(ret &lt; 0)
      {
          dev_err(dev, "mclk frequency is invalid\n");
          return ret;
      }
  
      ret = of_property_read_u32(dev-&gt;of_node, "mclk_source",
                                 (u32 *)&amp;(foo_data.mclk_source));
      if(ret &lt; 0)
      {
          dev_err(dev, "mclk source is invalid\n");
          return ret;
      }
  
      ret = of_property_read_u32(dev-&gt;of_node, "csi_id", &amp;(foo_data.csi));
      if(ret &lt; 0)
      {
          dev_err(dev, "csi_id invalid\n");
          return ret;
      }
  
      clk_prepare_enable(foo_data.sensor_clk);
      i2c_client0 = client;
  
      /* custom data structures are set here */   
  
      foo_reset();
  
      ret = foo_get_id();
  
      if(ret &lt; 0 /* || ret != foo_ID */)
      {
          clk_disable_unprepare(foo_data.sensor_clk);
          pr_warning("foo is not found\n");
          return -ENODEV;
      }
  
      clk_disable_unprepare(foo_data.sensor_clk);
      foo_int_device.priv = &amp;foo_data;
      ret = v4l2_int_device_register(&amp;foo_int_device);
  
      pr_info("foo is found\n");
      i2c0initialized = 1;
      return ret;
  }
  </code></pre>