This source file includes following definitions.
- pca9541_reg_write
 
- pca9541_reg_read
 
- pca9541_release_bus
 
- pca9541_arbitrate
 
- pca9541_select_chan
 
- pca9541_release_chan
 
- pca9541_probe
 
- pca9541_remove
 
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 #include <linux/delay.h>
  20 #include <linux/device.h>
  21 #include <linux/i2c.h>
  22 #include <linux/i2c-mux.h>
  23 #include <linux/jiffies.h>
  24 #include <linux/module.h>
  25 #include <linux/slab.h>
  26 
  27 
  28 
  29 
  30 
  31 
  32 
  33 
  34 
  35 
  36 
  37 
  38 
  39 
  40 
  41 
  42 #define PCA9541_CONTROL         0x01
  43 #define PCA9541_ISTAT           0x02
  44 
  45 #define PCA9541_CTL_MYBUS       (1 << 0)
  46 #define PCA9541_CTL_NMYBUS      (1 << 1)
  47 #define PCA9541_CTL_BUSON       (1 << 2)
  48 #define PCA9541_CTL_NBUSON      (1 << 3)
  49 #define PCA9541_CTL_BUSINIT     (1 << 4)
  50 #define PCA9541_CTL_TESTON      (1 << 6)
  51 #define PCA9541_CTL_NTESTON     (1 << 7)
  52 
  53 #define PCA9541_ISTAT_INTIN     (1 << 0)
  54 #define PCA9541_ISTAT_BUSINIT   (1 << 1)
  55 #define PCA9541_ISTAT_BUSOK     (1 << 2)
  56 #define PCA9541_ISTAT_BUSLOST   (1 << 3)
  57 #define PCA9541_ISTAT_MYTEST    (1 << 6)
  58 #define PCA9541_ISTAT_NMYTEST   (1 << 7)
  59 
  60 #define BUSON           (PCA9541_CTL_BUSON | PCA9541_CTL_NBUSON)
  61 #define MYBUS           (PCA9541_CTL_MYBUS | PCA9541_CTL_NMYBUS)
  62 #define mybus(x)        (!((x) & MYBUS) || ((x) & MYBUS) == MYBUS)
  63 #define busoff(x)       (!((x) & BUSON) || ((x) & BUSON) == BUSON)
  64 
  65 
  66 #define ARB_TIMEOUT     (HZ / 8)        
  67 #define ARB2_TIMEOUT    (HZ / 4)        
  68 
  69 
  70 #define SELECT_DELAY_SHORT      50
  71 #define SELECT_DELAY_LONG       1000
  72 
  73 struct pca9541 {
  74         struct i2c_client *client;
  75         unsigned long select_timeout;
  76         unsigned long arb_timeout;
  77 };
  78 
  79 static const struct i2c_device_id pca9541_id[] = {
  80         {"pca9541", 0},
  81         {}
  82 };
  83 
  84 MODULE_DEVICE_TABLE(i2c, pca9541_id);
  85 
  86 #ifdef CONFIG_OF
  87 static const struct of_device_id pca9541_of_match[] = {
  88         { .compatible = "nxp,pca9541" },
  89         {}
  90 };
  91 MODULE_DEVICE_TABLE(of, pca9541_of_match);
  92 #endif
  93 
  94 
  95 
  96 
  97 
  98 static int pca9541_reg_write(struct i2c_client *client, u8 command, u8 val)
  99 {
 100         struct i2c_adapter *adap = client->adapter;
 101         union i2c_smbus_data data = { .byte = val };
 102 
 103         return __i2c_smbus_xfer(adap, client->addr, client->flags,
 104                                 I2C_SMBUS_WRITE, command,
 105                                 I2C_SMBUS_BYTE_DATA, &data);
 106 }
 107 
 108 
 109 
 110 
 111 
 112 static int pca9541_reg_read(struct i2c_client *client, u8 command)
 113 {
 114         struct i2c_adapter *adap = client->adapter;
 115         union i2c_smbus_data data;
 116         int ret;
 117 
 118         ret = __i2c_smbus_xfer(adap, client->addr, client->flags,
 119                                I2C_SMBUS_READ, command,
 120                                I2C_SMBUS_BYTE_DATA, &data);
 121 
 122         return ret ?: data.byte;
 123 }
 124 
 125 
 126 
 127 
 128 
 129 
 130 static void pca9541_release_bus(struct i2c_client *client)
 131 {
 132         int reg;
 133 
 134         reg = pca9541_reg_read(client, PCA9541_CONTROL);
 135         if (reg >= 0 && !busoff(reg) && mybus(reg))
 136                 pca9541_reg_write(client, PCA9541_CONTROL,
 137                                   (reg & PCA9541_CTL_NBUSON) >> 1);
 138 }
 139 
 140 
 141 
 142 
 143 
 144 
 145 
 146 
 147 
 148 
 149 
 150 
 151 
 152 
 153 
 154 
 155 
 156 
 157 
 158 
 159 
 160 
 161 
 162 
 163 
 164 
 165 static const u8 pca9541_control[16] = {
 166         4, 0, 1, 5, 4, 4, 5, 5, 0, 0, 1, 1, 0, 4, 5, 1
 167 };
 168 
 169 
 170 
 171 
 172 
 173 
 174 
 175 
 176 
 177 static int pca9541_arbitrate(struct i2c_client *client)
 178 {
 179         struct i2c_mux_core *muxc = i2c_get_clientdata(client);
 180         struct pca9541 *data = i2c_mux_priv(muxc);
 181         int reg;
 182 
 183         reg = pca9541_reg_read(client, PCA9541_CONTROL);
 184         if (reg < 0)
 185                 return reg;
 186 
 187         if (busoff(reg)) {
 188                 int istat;
 189                 
 190 
 191 
 192 
 193                 istat = pca9541_reg_read(client, PCA9541_ISTAT);
 194                 if (!(istat & PCA9541_ISTAT_NMYTEST)
 195                     || time_is_before_eq_jiffies(data->arb_timeout)) {
 196                         
 197 
 198 
 199 
 200                         pca9541_reg_write(client,
 201                                           PCA9541_CONTROL,
 202                                           pca9541_control[reg & 0x0f]
 203                                           | PCA9541_CTL_NTESTON);
 204                         data->select_timeout = SELECT_DELAY_SHORT;
 205                 } else {
 206                         
 207 
 208 
 209 
 210                         data->select_timeout = SELECT_DELAY_LONG * 2;
 211                 }
 212         } else if (mybus(reg)) {
 213                 
 214 
 215 
 216 
 217                 if (reg & (PCA9541_CTL_NTESTON | PCA9541_CTL_BUSINIT))
 218                         pca9541_reg_write(client,
 219                                           PCA9541_CONTROL,
 220                                           reg & ~(PCA9541_CTL_NTESTON
 221                                                   | PCA9541_CTL_BUSINIT));
 222                 return 1;
 223         } else {
 224                 
 225 
 226 
 227 
 228 
 229                 data->select_timeout = SELECT_DELAY_LONG;
 230                 if (time_is_before_eq_jiffies(data->arb_timeout)) {
 231                         
 232                         pca9541_reg_write(client,
 233                                           PCA9541_CONTROL,
 234                                           pca9541_control[reg & 0x0f]
 235                                           | PCA9541_CTL_BUSINIT
 236                                           | PCA9541_CTL_NTESTON);
 237                 } else {
 238                         
 239                         if (!(reg & PCA9541_CTL_NTESTON))
 240                                 pca9541_reg_write(client,
 241                                                   PCA9541_CONTROL,
 242                                                   reg | PCA9541_CTL_NTESTON);
 243                 }
 244         }
 245         return 0;
 246 }
 247 
 248 static int pca9541_select_chan(struct i2c_mux_core *muxc, u32 chan)
 249 {
 250         struct pca9541 *data = i2c_mux_priv(muxc);
 251         struct i2c_client *client = data->client;
 252         int ret;
 253         unsigned long timeout = jiffies + ARB2_TIMEOUT;
 254                 
 255 
 256         data->arb_timeout = jiffies + ARB_TIMEOUT;
 257                 
 258 
 259         do {
 260                 ret = pca9541_arbitrate(client);
 261                 if (ret)
 262                         return ret < 0 ? ret : 0;
 263 
 264                 if (data->select_timeout == SELECT_DELAY_SHORT)
 265                         udelay(data->select_timeout);
 266                 else
 267                         msleep(data->select_timeout / 1000);
 268         } while (time_is_after_eq_jiffies(timeout));
 269 
 270         return -ETIMEDOUT;
 271 }
 272 
 273 static int pca9541_release_chan(struct i2c_mux_core *muxc, u32 chan)
 274 {
 275         struct pca9541 *data = i2c_mux_priv(muxc);
 276         struct i2c_client *client = data->client;
 277 
 278         pca9541_release_bus(client);
 279         return 0;
 280 }
 281 
 282 
 283 
 284 
 285 static int pca9541_probe(struct i2c_client *client,
 286                          const struct i2c_device_id *id)
 287 {
 288         struct i2c_adapter *adap = client->adapter;
 289         struct i2c_mux_core *muxc;
 290         struct pca9541 *data;
 291         int ret;
 292 
 293         if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE_DATA))
 294                 return -ENODEV;
 295 
 296         
 297 
 298 
 299 
 300         i2c_lock_bus(adap, I2C_LOCK_SEGMENT);
 301         pca9541_release_bus(client);
 302         i2c_unlock_bus(adap, I2C_LOCK_SEGMENT);
 303 
 304         
 305 
 306         muxc = i2c_mux_alloc(adap, &client->dev, 1, sizeof(*data),
 307                              I2C_MUX_ARBITRATOR,
 308                              pca9541_select_chan, pca9541_release_chan);
 309         if (!muxc)
 310                 return -ENOMEM;
 311 
 312         data = i2c_mux_priv(muxc);
 313         data->client = client;
 314 
 315         i2c_set_clientdata(client, muxc);
 316 
 317         ret = i2c_mux_add_adapter(muxc, 0, 0, 0);
 318         if (ret)
 319                 return ret;
 320 
 321         dev_info(&client->dev, "registered master selector for I2C %s\n",
 322                  client->name);
 323 
 324         return 0;
 325 }
 326 
 327 static int pca9541_remove(struct i2c_client *client)
 328 {
 329         struct i2c_mux_core *muxc = i2c_get_clientdata(client);
 330 
 331         i2c_mux_del_adapters(muxc);
 332         return 0;
 333 }
 334 
 335 static struct i2c_driver pca9541_driver = {
 336         .driver = {
 337                    .name = "pca9541",
 338                    .of_match_table = of_match_ptr(pca9541_of_match),
 339                    },
 340         .probe = pca9541_probe,
 341         .remove = pca9541_remove,
 342         .id_table = pca9541_id,
 343 };
 344 
 345 module_i2c_driver(pca9541_driver);
 346 
 347 MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
 348 MODULE_DESCRIPTION("PCA9541 I2C master selector driver");
 349 MODULE_LICENSE("GPL v2");