i2c: warning if rk610 is exist
authorkfx <kfx@rock-chips.com>
Tue, 13 Nov 2012 03:53:27 +0000 (11:53 +0800)
committerkfx <kfx@rock-chips.com>
Tue, 13 Nov 2012 03:53:27 +0000 (11:53 +0800)
e.g.
*************** WARNING ****************
i2c i2c-0: rk610 is exist, clients:
client: rk610_ctl, addr: 0x40
client: rk610_tvout, addr: 0x42
client: rk610_hdmi, addr: 0x46
client: rk610_i2c_codec, addr: 0x60
client: wm8326, addr: 0x34
****************************************

drivers/i2c/busses/i2c-rk30.c
drivers/i2c/i2c-core.c
include/linux/i2c.h

index 54a6d2b818ff6f95fcc4369a0d95d33ccd68be17..1383cca221c8f8fc1f1e3c6e048720769fb03169 100755 (executable)
@@ -15,6 +15,7 @@
 #include "i2c-rk30.h"
 #define TX_SETUP                        1
 
+static int i2c_max_adap = 0;
 void i2c_adap_sel(struct rk30_i2c *i2c, int nr, int adap_type)
 {
         i2c_writel((1 << I2C_ADAP_SEL_BIT(nr)) | (1 << I2C_ADAP_SEL_MASK(nr)) ,
@@ -202,6 +203,7 @@ static int rk30_i2c_probe(struct platform_device *pdev)
         i2c->is_div_from_arm[i2c->adap.nr] = pdata->is_div_from_arm;
 
         i2c->i2c_init_hw(i2c, 100 * 1000);
+        i2c_max_adap++;
        dev_info(&pdev->dev, "%s: RK30 I2C adapter\n", dev_name(&i2c->adap.dev));
        return 0;
 //err_none:
@@ -383,7 +385,16 @@ static void __exit i2c_detect_exit(void)
 module_init(i2c_detect_init);
 module_exit(i2c_detect_exit);
 
+static int __init i2c_detect_rk610(void)
+{
+        int i;
 
+        for(i = 0; i < i2c_max_adap; i++){
+                i2c_check_rk610_ex(i);
+        }
+        return 0;
+}
+late_initcall(i2c_detect_rk610);
 
 
 
index 3b18b4ef9c2c5bcee29b1c83d23755af92940f72..33d8df20b09c6811c13c5b53e29610345a397b8c 100755 (executable)
@@ -587,6 +587,55 @@ out_err_silent:
 }
 EXPORT_SYMBOL_GPL(i2c_new_device);
 #ifdef CONFIG_PLAT_RK
+#define RK610_KEY       "rk610"
+static int __i2c_client_print(struct device *dev, void *param)
+{
+        struct i2c_client *client = i2c_verify_client(dev);
+
+        if(client)
+                printk(KERN_WARNING "client: %s, addr: 0x%x\n", client->name, client->addr);
+        return 0;
+}
+static int __i2c_check_rk610_ex(struct device *dev, void *ex)
+{
+        struct i2c_client *client = i2c_verify_client(dev);
+
+        if(!client)
+                return 0;
+
+        if(strstr(client->name, RK610_KEY) != NULL)
+                *(int *)ex += 1 << 8;
+        else
+                *(int *)ex += 1;
+        return 0;
+}
+int i2c_check_rk610_ex(int nr)
+{
+        int ex = 0, rk610_ex = 0, oth_ex = 0;
+        struct i2c_adapter *adap = i2c_get_adapter(nr);
+
+        if(!adap){
+                printk(KERN_ERR "%s: adap(%d) is not exist\n", __func__, nr);
+                return -EINVAL;
+        }
+        device_for_each_child(&adap->dev, &ex, __i2c_check_rk610_ex);
+
+        if(ex & (1 << 8))
+                rk610_ex = 1;
+
+        oth_ex = ex & 0xff;
+
+        if(rk610_ex && oth_ex){
+                ex = 1;
+                printk(KERN_WARNING "******************* WARNING ********************\n");
+                dev_warn(&adap->dev, "%s is exist, clients:\n", RK610_KEY);
+                device_for_each_child(&adap->dev, NULL, __i2c_client_print);
+                printk(KERN_WARNING "************************************************\n");
+        }
+        else 
+                ex = 0;
+        return ex;
+}
 #ifdef CONFIG_I2C_RK30
 int i2c_add_device(int nr, struct i2c_board_info const *info)
 {
@@ -660,11 +709,16 @@ out_err_silent:
        return status;
 }
 #else
+int i2c_check_rk610_ex(int nr)
+{
+        return 0;
+}
 int i2c_add_device(int nr, struct i2c_board_info const *info)
 {
         return 0;
 }
 #endif
+EXPORT_SYMBOL_GPL(i2c_check_rk610_ex);
 EXPORT_SYMBOL_GPL(i2c_add_device);
 #endif
 
index d121f60bdb05677158153b371913d4835e51cd5d..2b58f67f36920d44cfe123674111ed81a400facd 100755 (executable)
@@ -71,6 +71,7 @@ extern int i2c_master_reg16_send(const struct i2c_client *client, const short re
 extern int i2c_master_reg16_recv(const struct i2c_client *client, const short regs, short *buf, int count, int scl_rate);
 extern int i2c_suspended(struct i2c_adapter *adap);
 extern int i2c_add_device(int nr, struct i2c_board_info const *info);
+extern int i2c_check_rk610_ex(int nr);
 #endif
 
 /* Transfer num messages.