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/property.h>
19 #include <linux/regmap.h>
20 #include <linux/slab.h>
22 #define LTC4305_MAX_NCHANS 2
23 #define LTC4306_MAX_NCHANS 4
25 #define LTC_REG_STATUS 0x0
26 #define LTC_REG_CONFIG 0x1
27 #define LTC_REG_MODE 0x2
28 #define LTC_REG_SWITCH 0x3
30 #define LTC_DOWNSTREAM_ACCL_EN BIT(6)
31 #define LTC_UPSTREAM_ACCL_EN BIT(7)
33 #define LTC_GPIO_ALL_INPUT 0xC0
34 #define LTC_SWITCH_MASK 0xF0
47 struct regmap
*regmap
;
48 struct gpio_chip gpiochip
;
49 const struct chip_desc
*chip
;
52 static const struct chip_desc chips
[] = {
54 .nchans
= LTC4305_MAX_NCHANS
,
57 .nchans
= LTC4306_MAX_NCHANS
,
62 static bool ltc4306_is_volatile_reg(struct device
*dev
, unsigned int reg
)
64 return reg
== LTC_REG_CONFIG
;
67 static const struct regmap_config ltc4306_regmap_config
= {
70 .max_register
= LTC_REG_SWITCH
,
71 .volatile_reg
= ltc4306_is_volatile_reg
,
72 .cache_type
= REGCACHE_FLAT
,
75 static int ltc4306_gpio_get(struct gpio_chip
*chip
, unsigned int offset
)
77 struct ltc4306
*data
= gpiochip_get_data(chip
);
81 ret
= regmap_read(data
->regmap
, LTC_REG_CONFIG
, &val
);
85 return !!(val
& BIT(1 - offset
));
88 static void ltc4306_gpio_set(struct gpio_chip
*chip
, unsigned int offset
,
91 struct ltc4306
*data
= gpiochip_get_data(chip
);
93 regmap_update_bits(data
->regmap
, LTC_REG_CONFIG
, BIT(5 - offset
),
94 value
? BIT(5 - offset
) : 0);
97 static int ltc4306_gpio_get_direction(struct gpio_chip
*chip
,
100 struct ltc4306
*data
= gpiochip_get_data(chip
);
104 ret
= regmap_read(data
->regmap
, LTC_REG_MODE
, &val
);
108 return !!(val
& BIT(7 - offset
));
111 static int ltc4306_gpio_direction_input(struct gpio_chip
*chip
,
114 struct ltc4306
*data
= gpiochip_get_data(chip
);
116 return regmap_update_bits(data
->regmap
, LTC_REG_MODE
,
117 BIT(7 - offset
), BIT(7 - offset
));
120 static int ltc4306_gpio_direction_output(struct gpio_chip
*chip
,
121 unsigned int offset
, int value
)
123 struct ltc4306
*data
= gpiochip_get_data(chip
);
125 ltc4306_gpio_set(chip
, offset
, value
);
126 return regmap_update_bits(data
->regmap
, LTC_REG_MODE
,
130 static int ltc4306_gpio_set_config(struct gpio_chip
*chip
,
131 unsigned int offset
, unsigned long config
)
133 struct ltc4306
*data
= gpiochip_get_data(chip
);
136 switch (pinconf_to_config_param(config
)) {
137 case PIN_CONFIG_DRIVE_OPEN_DRAIN
:
140 case PIN_CONFIG_DRIVE_PUSH_PULL
:
141 val
= BIT(4 - offset
);
147 return regmap_update_bits(data
->regmap
, LTC_REG_MODE
,
148 BIT(4 - offset
), val
);
151 static int ltc4306_gpio_init(struct ltc4306
*data
)
153 struct device
*dev
= regmap_get_device(data
->regmap
);
155 if (!data
->chip
->num_gpios
)
158 data
->gpiochip
.label
= dev_name(dev
);
159 data
->gpiochip
.base
= -1;
160 data
->gpiochip
.ngpio
= data
->chip
->num_gpios
;
161 data
->gpiochip
.parent
= dev
;
162 data
->gpiochip
.can_sleep
= true;
163 data
->gpiochip
.get_direction
= ltc4306_gpio_get_direction
;
164 data
->gpiochip
.direction_input
= ltc4306_gpio_direction_input
;
165 data
->gpiochip
.direction_output
= ltc4306_gpio_direction_output
;
166 data
->gpiochip
.get
= ltc4306_gpio_get
;
167 data
->gpiochip
.set
= ltc4306_gpio_set
;
168 data
->gpiochip
.set_config
= ltc4306_gpio_set_config
;
169 data
->gpiochip
.owner
= THIS_MODULE
;
171 /* gpiolib assumes all GPIOs default input */
172 regmap_write(data
->regmap
, LTC_REG_MODE
, LTC_GPIO_ALL_INPUT
);
174 return devm_gpiochip_add_data(dev
, &data
->gpiochip
, data
);
177 static int ltc4306_select_mux(struct i2c_mux_core
*muxc
, u32 chan
)
179 struct ltc4306
*data
= i2c_mux_priv(muxc
);
181 return regmap_update_bits(data
->regmap
, LTC_REG_SWITCH
,
182 LTC_SWITCH_MASK
, BIT(7 - chan
));
185 static int ltc4306_deselect_mux(struct i2c_mux_core
*muxc
, u32 chan
)
187 struct ltc4306
*data
= i2c_mux_priv(muxc
);
189 return regmap_update_bits(data
->regmap
, LTC_REG_SWITCH
,
193 static const struct i2c_device_id ltc4306_id
[] = {
194 { "ltc4305", ltc_4305
},
195 { "ltc4306", ltc_4306
},
198 MODULE_DEVICE_TABLE(i2c
, ltc4306_id
);
200 static const struct of_device_id ltc4306_of_match
[] = {
201 { .compatible
= "lltc,ltc4305", .data
= &chips
[ltc_4305
] },
202 { .compatible
= "lltc,ltc4306", .data
= &chips
[ltc_4306
] },
205 MODULE_DEVICE_TABLE(of
, ltc4306_of_match
);
207 static int ltc4306_probe(struct i2c_client
*client
)
209 struct i2c_adapter
*adap
= client
->adapter
;
210 const struct chip_desc
*chip
;
211 struct i2c_mux_core
*muxc
;
212 struct ltc4306
*data
;
213 struct gpio_desc
*gpio
;
215 unsigned int val
= 0;
218 chip
= of_device_get_match_data(&client
->dev
);
221 chip
= &chips
[i2c_match_id(ltc4306_id
, client
)->driver_data
];
223 idle_disc
= device_property_read_bool(&client
->dev
,
224 "i2c-mux-idle-disconnect");
226 muxc
= i2c_mux_alloc(adap
, &client
->dev
,
227 chip
->nchans
, sizeof(*data
),
228 I2C_MUX_LOCKED
, ltc4306_select_mux
,
229 idle_disc
? ltc4306_deselect_mux
: NULL
);
232 data
= i2c_mux_priv(muxc
);
235 i2c_set_clientdata(client
, muxc
);
237 data
->regmap
= devm_regmap_init_i2c(client
, <c4306_regmap_config
);
238 if (IS_ERR(data
->regmap
)) {
239 ret
= PTR_ERR(data
->regmap
);
240 dev_err(&client
->dev
, "Failed to allocate register map: %d\n",
245 /* Reset and enable the mux if an enable GPIO is specified. */
246 gpio
= devm_gpiod_get_optional(&client
->dev
, "enable", GPIOD_OUT_LOW
);
248 return PTR_ERR(gpio
);
252 gpiod_set_value(gpio
, 1);
256 * Write the mux register at addr to verify
257 * that the mux is in fact present. This also
258 * initializes the mux to disconnected state.
260 if (regmap_write(data
->regmap
, LTC_REG_SWITCH
, 0) < 0) {
261 dev_warn(&client
->dev
, "probe failed\n");
265 if (device_property_read_bool(&client
->dev
,
266 "ltc,downstream-accelerators-enable"))
267 val
|= LTC_DOWNSTREAM_ACCL_EN
;
269 if (device_property_read_bool(&client
->dev
,
270 "ltc,upstream-accelerators-enable"))
271 val
|= LTC_UPSTREAM_ACCL_EN
;
273 if (regmap_write(data
->regmap
, LTC_REG_CONFIG
, val
) < 0)
276 ret
= ltc4306_gpio_init(data
);
280 /* Now create an adapter for each channel */
281 for (num
= 0; num
< chip
->nchans
; num
++) {
282 ret
= i2c_mux_add_adapter(muxc
, 0, num
);
284 i2c_mux_del_adapters(muxc
);
289 dev_info(&client
->dev
,
290 "registered %d multiplexed busses for I2C switch %s\n",
296 static void ltc4306_remove(struct i2c_client
*client
)
298 struct i2c_mux_core
*muxc
= i2c_get_clientdata(client
);
300 i2c_mux_del_adapters(muxc
);
303 static struct i2c_driver ltc4306_driver
= {
306 .of_match_table
= of_match_ptr(ltc4306_of_match
),
308 .probe
= ltc4306_probe
,
309 .remove
= ltc4306_remove
,
310 .id_table
= ltc4306_id
,
313 module_i2c_driver(ltc4306_driver
);
315 MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
316 MODULE_DESCRIPTION("Linear Technology LTC4306, LTC4305 I2C mux/switch driver");
317 MODULE_LICENSE("GPL v2");