Merge tag 'trace-v6.9-2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux...
[sfrench/cifs-2.6.git] / drivers / i2c / muxes / i2c-mux-pca954x.c
index 2219062104fbca4fcd23b89012090c7c30602790..f5dfc33b97c0ab94dfee90ae29d81c69395f180b 100644 (file)
 
 #define PCA954X_IRQ_OFFSET 4
 
+/*
+ * MAX7357's configuration register is writeable after POR, but
+ * can be locked by setting the basic mode bit. MAX7358 configuration
+ * register is locked by default and needs to be unlocked first.
+ * The configuration register holds the following settings:
+ */
+#define MAX7357_CONF_INT_ENABLE                        BIT(0)
+#define MAX7357_CONF_FLUSH_OUT                 BIT(1)
+#define MAX7357_CONF_RELEASE_INT               BIT(2)
+#define MAX7357_CONF_DISCON_SINGLE_CHAN                BIT(4)
+#define MAX7357_CONF_PRECONNECT_TEST           BIT(7)
+
+#define MAX7357_POR_DEFAULT_CONF               MAX7357_CONF_INT_ENABLE
+
 enum pca_type {
        max_7356,
        max_7357,
@@ -470,7 +484,34 @@ static int pca954x_init(struct i2c_client *client, struct pca954x *data)
        else
                data->last_chan = 0; /* Disconnect multiplexer */
 
-       ret = i2c_smbus_write_byte(client, data->last_chan);
+       if (device_is_compatible(&client->dev, "maxim,max7357")) {
+               if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) {
+                       u8 conf = MAX7357_POR_DEFAULT_CONF;
+                       /*
+                        * The interrupt signal is shared with the reset pin. Release the
+                        * interrupt after 1.6 seconds to allow using the pin as reset.
+                        */
+                       conf |= MAX7357_CONF_RELEASE_INT;
+
+                       if (device_property_read_bool(&client->dev, "maxim,isolate-stuck-channel"))
+                               conf |= MAX7357_CONF_DISCON_SINGLE_CHAN;
+                       if (device_property_read_bool(&client->dev,
+                                                     "maxim,send-flush-out-sequence"))
+                               conf |= MAX7357_CONF_FLUSH_OUT;
+                       if (device_property_read_bool(&client->dev,
+                                                     "maxim,preconnection-wiggle-test-enable"))
+                               conf |= MAX7357_CONF_PRECONNECT_TEST;
+
+                       ret = i2c_smbus_write_byte_data(client, data->last_chan, conf);
+               } else {
+                       dev_warn(&client->dev, "Write byte data not supported."
+                                "Cannot enable enhanced mode features\n");
+                       ret = i2c_smbus_write_byte(client, data->last_chan);
+               }
+       } else {
+               ret = i2c_smbus_write_byte(client, data->last_chan);
+       }
+
        if (ret < 0)
                data->last_chan = 0;