1 // SPDX-License-Identifier: GPL-2.0-only
3 * Linear Technology LTC4306 and LTC4305 I2C multiplexer/switch
5 * Copyright (C) 2017 Analog Devices Inc.
7 * Based on: i2c-mux-pca954x.c
9 * Datasheet: http://cds.linear.com/docs/en/datasheet/4306.pdf
12 #include <linux/gpio/consumer.h>
13 #include <linux/gpio/driver.h>
14 #include <linux/i2c-mux.h>
15 #include <linux/i2c.h>
16 #include <linux/module.h>
18 #include <linux/of_device.h>
19 #include <linux/property.h>
20 #include <linux/regmap.h>
21 #include <linux/slab.h>
23 #define LTC4305_MAX_NCHANS 2
24 #define LTC4306_MAX_NCHANS 4
26 #define LTC_REG_STATUS 0x0
27 #define LTC_REG_CONFIG 0x1
28 #define LTC_REG_MODE 0x2
29 #define LTC_REG_SWITCH 0x3
31 #define LTC_DOWNSTREAM_ACCL_EN BIT(6)
32 #define LTC_UPSTREAM_ACCL_EN BIT(7)
34 #define LTC_GPIO_ALL_INPUT 0xC0
35 #define LTC_SWITCH_MASK 0xF0
48 struct regmap
*regmap
;
49 struct gpio_chip gpiochip
;
50 const struct chip_desc
*chip
;
53 static const struct chip_desc chips
[] = {
55 .nchans
= LTC4305_MAX_NCHANS
,
58 .nchans
= LTC4306_MAX_NCHANS
,
63 static bool ltc4306_is_volatile_reg(struct device
*dev
, unsigned int reg
)
65 return (reg
== LTC_REG_CONFIG
) ? true : false;
68 static const struct regmap_config ltc4306_regmap_config
= {
71 .max_register
= LTC_REG_SWITCH
,
72 .volatile_reg
= ltc4306_is_volatile_reg
,
73 .cache_type
= REGCACHE_FLAT
,
76 static int ltc4306_gpio_get(struct gpio_chip
*chip
, unsigned int offset
)
78 struct ltc4306
*data
= gpiochip_get_data(chip
);
82 ret
= regmap_read(data
->regmap
, LTC_REG_CONFIG
, &val
);
86 return !!(val
& BIT(1 - offset
));
89 static void ltc4306_gpio_set(struct gpio_chip
*chip
, unsigned int offset
,
92 struct ltc4306
*data
= gpiochip_get_data(chip
);
94 regmap_update_bits(data
->regmap
, LTC_REG_CONFIG
, BIT(5 - offset
),
95 value
? BIT(5 - offset
) : 0);
98 static int ltc4306_gpio_get_direction(struct gpio_chip
*chip
,
101 struct ltc4306
*data
= gpiochip_get_data(chip
);
105 ret
= regmap_read(data
->regmap
, LTC_REG_MODE
, &val
);
109 return !!(val
& BIT(7 - offset
));
112 static int ltc4306_gpio_direction_input(struct gpio_chip
*chip
,
115 struct ltc4306
*data
= gpiochip_get_data(chip
);
117 return regmap_update_bits(data
->regmap
, LTC_REG_MODE
,
118 BIT(7 - offset
), BIT(7 - offset
));
121 static int ltc4306_gpio_direction_output(struct gpio_chip
*chip
,
122 unsigned int offset
, int value
)
124 struct ltc4306
*data
= gpiochip_get_data(chip
);
126 ltc4306_gpio_set(chip
, offset
, value
);
127 return regmap_update_bits(data
->regmap
, LTC_REG_MODE
,
131 static int ltc4306_gpio_set_config(struct gpio_chip
*chip
,
132 unsigned int offset
, unsigned long config
)
134 struct ltc4306
*data
= gpiochip_get_data(chip
);
137 switch (pinconf_to_config_param(config
)) {
138 case PIN_CONFIG_DRIVE_OPEN_DRAIN
:
141 case PIN_CONFIG_DRIVE_PUSH_PULL
:
142 val
= BIT(4 - offset
);
148 return regmap_update_bits(data
->regmap
, LTC_REG_MODE
,
149 BIT(4 - offset
), val
);
152 static int ltc4306_gpio_init(struct ltc4306
*data
)
154 struct device
*dev
= regmap_get_device(data
->regmap
);
156 if (!data
->chip
->num_gpios
)
159 data
->gpiochip
.label
= dev_name(dev
);
160 data
->gpiochip
.base
= -1;
161 data
->gpiochip
.ngpio
= data
->chip
->num_gpios
;
162 data
->gpiochip
.parent
= dev
;
163 data
->gpiochip
.can_sleep
= true;
164 data
->gpiochip
.get_direction
= ltc4306_gpio_get_direction
;
165 data
->gpiochip
.direction_input
= ltc4306_gpio_direction_input
;
166 data
->gpiochip
.direction_output
= ltc4306_gpio_direction_output
;
167 data
->gpiochip
.get
= ltc4306_gpio_get
;
168 data
->gpiochip
.set
= ltc4306_gpio_set
;
169 data
->gpiochip
.set_config
= ltc4306_gpio_set_config
;
170 data
->gpiochip
.owner
= THIS_MODULE
;
172 /* gpiolib assumes all GPIOs default input */
173 regmap_write(data
->regmap
, LTC_REG_MODE
, LTC_GPIO_ALL_INPUT
);
175 return devm_gpiochip_add_data(dev
, &data
->gpiochip
, data
);
178 static int ltc4306_select_mux(struct i2c_mux_core
*muxc
, u32 chan
)
180 struct ltc4306
*data
= i2c_mux_priv(muxc
);
182 return regmap_update_bits(data
->regmap
, LTC_REG_SWITCH
,
183 LTC_SWITCH_MASK
, BIT(7 - chan
));
186 static int ltc4306_deselect_mux(struct i2c_mux_core
*muxc
, u32 chan
)
188 struct ltc4306
*data
= i2c_mux_priv(muxc
);
190 return regmap_update_bits(data
->regmap
, LTC_REG_SWITCH
,
194 static const struct i2c_device_id ltc4306_id
[] = {
195 { "ltc4305", ltc_4305
},
196 { "ltc4306", ltc_4306
},
199 MODULE_DEVICE_TABLE(i2c
, ltc4306_id
);
201 static const struct of_device_id ltc4306_of_match
[] = {
202 { .compatible
= "lltc,ltc4305", .data
= &chips
[ltc_4305
] },
203 { .compatible
= "lltc,ltc4306", .data
= &chips
[ltc_4306
] },
206 MODULE_DEVICE_TABLE(of
, ltc4306_of_match
);
208 static int ltc4306_probe(struct i2c_client
*client
)
210 struct i2c_adapter
*adap
= client
->adapter
;
211 const struct chip_desc
*chip
;
212 struct i2c_mux_core
*muxc
;
213 struct ltc4306
*data
;
214 struct gpio_desc
*gpio
;
216 unsigned int val
= 0;
219 chip
= of_device_get_match_data(&client
->dev
);
222 chip
= &chips
[i2c_match_id(ltc4306_id
, client
)->driver_data
];
224 idle_disc
= device_property_read_bool(&client
->dev
,
225 "i2c-mux-idle-disconnect");
227 muxc
= i2c_mux_alloc(adap
, &client
->dev
,
228 chip
->nchans
, sizeof(*data
),
229 I2C_MUX_LOCKED
, ltc4306_select_mux
,
230 idle_disc
? ltc4306_deselect_mux
: NULL
);
233 data
= i2c_mux_priv(muxc
);
236 i2c_set_clientdata(client
, muxc
);
238 data
->regmap
= devm_regmap_init_i2c(client
, <c4306_regmap_config
);
239 if (IS_ERR(data
->regmap
)) {
240 ret
= PTR_ERR(data
->regmap
);
241 dev_err(&client
->dev
, "Failed to allocate register map: %d\n",
246 /* Reset and enable the mux if an enable GPIO is specified. */
247 gpio
= devm_gpiod_get_optional(&client
->dev
, "enable", GPIOD_OUT_LOW
);
249 return PTR_ERR(gpio
);
253 gpiod_set_value(gpio
, 1);
257 * Write the mux register at addr to verify
258 * that the mux is in fact present. This also
259 * initializes the mux to disconnected state.
261 if (regmap_write(data
->regmap
, LTC_REG_SWITCH
, 0) < 0) {
262 dev_warn(&client
->dev
, "probe failed\n");
266 if (device_property_read_bool(&client
->dev
,
267 "ltc,downstream-accelerators-enable"))
268 val
|= LTC_DOWNSTREAM_ACCL_EN
;
270 if (device_property_read_bool(&client
->dev
,
271 "ltc,upstream-accelerators-enable"))
272 val
|= LTC_UPSTREAM_ACCL_EN
;
274 if (regmap_write(data
->regmap
, LTC_REG_CONFIG
, val
) < 0)
277 ret
= ltc4306_gpio_init(data
);
281 /* Now create an adapter for each channel */
282 for (num
= 0; num
< chip
->nchans
; num
++) {
283 ret
= i2c_mux_add_adapter(muxc
, 0, num
, 0);
285 i2c_mux_del_adapters(muxc
);
290 dev_info(&client
->dev
,
291 "registered %d multiplexed busses for I2C switch %s\n",
297 static int ltc4306_remove(struct i2c_client
*client
)
299 struct i2c_mux_core
*muxc
= i2c_get_clientdata(client
);
301 i2c_mux_del_adapters(muxc
);
306 static struct i2c_driver ltc4306_driver
= {
309 .of_match_table
= of_match_ptr(ltc4306_of_match
),
311 .probe_new
= ltc4306_probe
,
312 .remove
= ltc4306_remove
,
313 .id_table
= ltc4306_id
,
316 module_i2c_driver(ltc4306_driver
);
318 MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
319 MODULE_DESCRIPTION("Linear Technology LTC4306, LTC4305 I2C mux/switch driver");
320 MODULE_LICENSE("GPL v2");