2 * Linear Technology LTC4306 and LTC4305 I2C multiplexer/switch
4 * Copyright (C) 2017 Analog Devices Inc.
6 * Licensed under the GPL-2.
8 * Based on: i2c-mux-pca954x.c
10 * Datasheet: http://cds.linear.com/docs/en/datasheet/4306.pdf
13 #include <linux/gpio/consumer.h>
14 #include <linux/gpio/driver.h>
15 #include <linux/i2c-mux.h>
16 #include <linux/i2c.h>
17 #include <linux/module.h>
19 #include <linux/of_device.h>
20 #include <linux/property.h>
21 #include <linux/regmap.h>
22 #include <linux/slab.h>
24 #define LTC4305_MAX_NCHANS 2
25 #define LTC4306_MAX_NCHANS 4
27 #define LTC_REG_STATUS 0x0
28 #define LTC_REG_CONFIG 0x1
29 #define LTC_REG_MODE 0x2
30 #define LTC_REG_SWITCH 0x3
32 #define LTC_DOWNSTREAM_ACCL_EN BIT(6)
33 #define LTC_UPSTREAM_ACCL_EN BIT(7)
35 #define LTC_GPIO_ALL_INPUT 0xC0
36 #define LTC_SWITCH_MASK 0xF0
49 struct regmap
*regmap
;
50 struct gpio_chip gpiochip
;
51 const struct chip_desc
*chip
;
54 static const struct chip_desc chips
[] = {
56 .nchans
= LTC4305_MAX_NCHANS
,
59 .nchans
= LTC4306_MAX_NCHANS
,
64 static bool ltc4306_is_volatile_reg(struct device
*dev
, unsigned int reg
)
66 return (reg
== LTC_REG_CONFIG
) ? true : false;
69 static const struct regmap_config ltc4306_regmap_config
= {
72 .max_register
= LTC_REG_SWITCH
,
73 .volatile_reg
= ltc4306_is_volatile_reg
,
74 .cache_type
= REGCACHE_FLAT
,
77 static int ltc4306_gpio_get(struct gpio_chip
*chip
, unsigned int offset
)
79 struct ltc4306
*data
= gpiochip_get_data(chip
);
83 ret
= regmap_read(data
->regmap
, LTC_REG_CONFIG
, &val
);
87 return !!(val
& BIT(1 - offset
));
90 static void ltc4306_gpio_set(struct gpio_chip
*chip
, unsigned int offset
,
93 struct ltc4306
*data
= gpiochip_get_data(chip
);
95 regmap_update_bits(data
->regmap
, LTC_REG_CONFIG
, BIT(5 - offset
),
96 value
? BIT(5 - offset
) : 0);
99 static int ltc4306_gpio_get_direction(struct gpio_chip
*chip
,
102 struct ltc4306
*data
= gpiochip_get_data(chip
);
106 ret
= regmap_read(data
->regmap
, LTC_REG_MODE
, &val
);
110 return !!(val
& BIT(7 - offset
));
113 static int ltc4306_gpio_direction_input(struct gpio_chip
*chip
,
116 struct ltc4306
*data
= gpiochip_get_data(chip
);
118 return regmap_update_bits(data
->regmap
, LTC_REG_MODE
,
119 BIT(7 - offset
), BIT(7 - offset
));
122 static int ltc4306_gpio_direction_output(struct gpio_chip
*chip
,
123 unsigned int offset
, int value
)
125 struct ltc4306
*data
= gpiochip_get_data(chip
);
127 ltc4306_gpio_set(chip
, offset
, value
);
128 return regmap_update_bits(data
->regmap
, LTC_REG_MODE
,
132 static int ltc4306_gpio_set_config(struct gpio_chip
*chip
,
133 unsigned int offset
, unsigned long config
)
135 struct ltc4306
*data
= gpiochip_get_data(chip
);
138 switch (pinconf_to_config_param(config
)) {
139 case PIN_CONFIG_DRIVE_OPEN_DRAIN
:
142 case PIN_CONFIG_DRIVE_PUSH_PULL
:
143 val
= BIT(4 - offset
);
149 return regmap_update_bits(data
->regmap
, LTC_REG_MODE
,
150 BIT(4 - offset
), val
);
153 static int ltc4306_gpio_init(struct ltc4306
*data
)
155 struct device
*dev
= regmap_get_device(data
->regmap
);
157 if (!data
->chip
->num_gpios
)
160 data
->gpiochip
.label
= dev_name(dev
);
161 data
->gpiochip
.base
= -1;
162 data
->gpiochip
.ngpio
= data
->chip
->num_gpios
;
163 data
->gpiochip
.parent
= dev
;
164 data
->gpiochip
.can_sleep
= true;
165 data
->gpiochip
.get_direction
= ltc4306_gpio_get_direction
;
166 data
->gpiochip
.direction_input
= ltc4306_gpio_direction_input
;
167 data
->gpiochip
.direction_output
= ltc4306_gpio_direction_output
;
168 data
->gpiochip
.get
= ltc4306_gpio_get
;
169 data
->gpiochip
.set
= ltc4306_gpio_set
;
170 data
->gpiochip
.set_config
= ltc4306_gpio_set_config
;
171 data
->gpiochip
.owner
= THIS_MODULE
;
173 /* gpiolib assumes all GPIOs default input */
174 regmap_write(data
->regmap
, LTC_REG_MODE
, LTC_GPIO_ALL_INPUT
);
176 return devm_gpiochip_add_data(dev
, &data
->gpiochip
, data
);
179 static int ltc4306_select_mux(struct i2c_mux_core
*muxc
, u32 chan
)
181 struct ltc4306
*data
= i2c_mux_priv(muxc
);
183 return regmap_update_bits(data
->regmap
, LTC_REG_SWITCH
,
184 LTC_SWITCH_MASK
, BIT(7 - chan
));
187 static int ltc4306_deselect_mux(struct i2c_mux_core
*muxc
, u32 chan
)
189 struct ltc4306
*data
= i2c_mux_priv(muxc
);
191 return regmap_update_bits(data
->regmap
, LTC_REG_SWITCH
,
195 static const struct i2c_device_id ltc4306_id
[] = {
196 { "ltc4305", ltc_4305
},
197 { "ltc4306", ltc_4306
},
200 MODULE_DEVICE_TABLE(i2c
, ltc4306_id
);
202 static const struct of_device_id ltc4306_of_match
[] = {
203 { .compatible
= "lltc,ltc4305", .data
= &chips
[ltc_4305
] },
204 { .compatible
= "lltc,ltc4306", .data
= &chips
[ltc_4306
] },
207 MODULE_DEVICE_TABLE(of
, ltc4306_of_match
);
209 static int ltc4306_probe(struct i2c_client
*client
)
211 struct i2c_adapter
*adap
= to_i2c_adapter(client
->dev
.parent
);
212 const struct chip_desc
*chip
;
213 struct i2c_mux_core
*muxc
;
214 struct ltc4306
*data
;
215 struct gpio_desc
*gpio
;
217 unsigned int val
= 0;
220 chip
= of_device_get_match_data(&client
->dev
);
223 chip
= &chips
[i2c_match_id(ltc4306_id
, client
)->driver_data
];
225 idle_disc
= device_property_read_bool(&client
->dev
,
226 "i2c-mux-idle-disconnect");
228 muxc
= i2c_mux_alloc(adap
, &client
->dev
,
229 chip
->nchans
, sizeof(*data
),
230 I2C_MUX_LOCKED
, ltc4306_select_mux
,
231 idle_disc
? ltc4306_deselect_mux
: NULL
);
234 data
= i2c_mux_priv(muxc
);
237 i2c_set_clientdata(client
, muxc
);
239 data
->regmap
= devm_regmap_init_i2c(client
, <c4306_regmap_config
);
240 if (IS_ERR(data
->regmap
)) {
241 ret
= PTR_ERR(data
->regmap
);
242 dev_err(&client
->dev
, "Failed to allocate register map: %d\n",
247 /* Reset and enable the mux if an enable GPIO is specified. */
248 gpio
= devm_gpiod_get_optional(&client
->dev
, "enable", GPIOD_OUT_LOW
);
250 return PTR_ERR(gpio
);
254 gpiod_set_value(gpio
, 1);
258 * Write the mux register at addr to verify
259 * that the mux is in fact present. This also
260 * initializes the mux to disconnected state.
262 if (regmap_write(data
->regmap
, LTC_REG_SWITCH
, 0) < 0) {
263 dev_warn(&client
->dev
, "probe failed\n");
267 if (device_property_read_bool(&client
->dev
,
268 "ltc,downstream-accelerators-enable"))
269 val
|= LTC_DOWNSTREAM_ACCL_EN
;
271 if (device_property_read_bool(&client
->dev
,
272 "ltc,upstream-accelerators-enable"))
273 val
|= LTC_UPSTREAM_ACCL_EN
;
275 if (regmap_write(data
->regmap
, LTC_REG_CONFIG
, val
) < 0)
278 ret
= ltc4306_gpio_init(data
);
282 /* Now create an adapter for each channel */
283 for (num
= 0; num
< chip
->nchans
; num
++) {
284 ret
= i2c_mux_add_adapter(muxc
, 0, num
, 0);
286 i2c_mux_del_adapters(muxc
);
291 dev_info(&client
->dev
,
292 "registered %d multiplexed busses for I2C switch %s\n",
298 static int ltc4306_remove(struct i2c_client
*client
)
300 struct i2c_mux_core
*muxc
= i2c_get_clientdata(client
);
302 i2c_mux_del_adapters(muxc
);
307 static struct i2c_driver ltc4306_driver
= {
310 .of_match_table
= of_match_ptr(ltc4306_of_match
),
312 .probe_new
= ltc4306_probe
,
313 .remove
= ltc4306_remove
,
314 .id_table
= ltc4306_id
,
317 module_i2c_driver(ltc4306_driver
);
319 MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
320 MODULE_DESCRIPTION("Linear Technology LTC4306, LTC4305 I2C mux/switch driver");
321 MODULE_LICENSE("GPL v2");