Lines Matching +full:i2c +full:- +full:mux +full:- +full:idle +full:- +full:disconnect
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Linear Technology LTC4306 and LTC4305 I2C multiplexer/switch
7 * Based on: i2c-mux-pca954x.c
14 #include <linux/i2c-mux.h>
15 #include <linux/i2c.h>
81 ret = regmap_read(data->regmap, LTC_REG_CONFIG, &val); in ltc4306_gpio_get()
85 return !!(val & BIT(1 - offset)); in ltc4306_gpio_get()
93 return regmap_update_bits(data->regmap, LTC_REG_CONFIG, in ltc4306_gpio_set()
94 BIT(5 - offset), value ? BIT(5 - offset) : 0); in ltc4306_gpio_set()
104 ret = regmap_read(data->regmap, LTC_REG_MODE, &val); in ltc4306_gpio_get_direction()
108 return !!(val & BIT(7 - offset)); in ltc4306_gpio_get_direction()
116 return regmap_update_bits(data->regmap, LTC_REG_MODE, in ltc4306_gpio_direction_input()
117 BIT(7 - offset), BIT(7 - offset)); in ltc4306_gpio_direction_input()
126 return regmap_update_bits(data->regmap, LTC_REG_MODE, in ltc4306_gpio_direction_output()
127 BIT(7 - offset), 0); in ltc4306_gpio_direction_output()
141 val = BIT(4 - offset); in ltc4306_gpio_set_config()
144 return -ENOTSUPP; in ltc4306_gpio_set_config()
147 return regmap_update_bits(data->regmap, LTC_REG_MODE, in ltc4306_gpio_set_config()
148 BIT(4 - offset), val); in ltc4306_gpio_set_config()
153 struct device *dev = regmap_get_device(data->regmap); in ltc4306_gpio_init()
155 if (!data->chip->num_gpios) in ltc4306_gpio_init()
158 data->gpiochip.label = dev_name(dev); in ltc4306_gpio_init()
159 data->gpiochip.base = -1; in ltc4306_gpio_init()
160 data->gpiochip.ngpio = data->chip->num_gpios; in ltc4306_gpio_init()
161 data->gpiochip.parent = dev; in ltc4306_gpio_init()
162 data->gpiochip.can_sleep = true; in ltc4306_gpio_init()
163 data->gpiochip.get_direction = ltc4306_gpio_get_direction; in ltc4306_gpio_init()
164 data->gpiochip.direction_input = ltc4306_gpio_direction_input; in ltc4306_gpio_init()
165 data->gpiochip.direction_output = ltc4306_gpio_direction_output; in ltc4306_gpio_init()
166 data->gpiochip.get = ltc4306_gpio_get; in ltc4306_gpio_init()
167 data->gpiochip.set = ltc4306_gpio_set; in ltc4306_gpio_init()
168 data->gpiochip.set_config = ltc4306_gpio_set_config; in ltc4306_gpio_init()
169 data->gpiochip.owner = THIS_MODULE; in ltc4306_gpio_init()
172 regmap_write(data->regmap, LTC_REG_MODE, LTC_GPIO_ALL_INPUT); in ltc4306_gpio_init()
174 return devm_gpiochip_add_data(dev, &data->gpiochip, data); in ltc4306_gpio_init()
181 return regmap_update_bits(data->regmap, LTC_REG_SWITCH, in ltc4306_select_mux()
182 LTC_SWITCH_MASK, BIT(7 - chan)); in ltc4306_select_mux()
189 return regmap_update_bits(data->regmap, LTC_REG_SWITCH, in ltc4306_deselect_mux()
198 MODULE_DEVICE_TABLE(i2c, ltc4306_id);
209 struct i2c_adapter *adap = client->adapter; in ltc4306_probe()
218 chip = of_device_get_match_data(&client->dev); in ltc4306_probe()
221 chip = &chips[i2c_match_id(ltc4306_id, client)->driver_data]; in ltc4306_probe()
223 idle_disc = device_property_read_bool(&client->dev, in ltc4306_probe()
224 "i2c-mux-idle-disconnect"); in ltc4306_probe()
226 muxc = i2c_mux_alloc(adap, &client->dev, in ltc4306_probe()
227 chip->nchans, sizeof(*data), in ltc4306_probe()
231 return -ENOMEM; in ltc4306_probe()
233 data->chip = chip; in ltc4306_probe()
237 data->regmap = devm_regmap_init_i2c(client, <c4306_regmap_config); in ltc4306_probe()
238 if (IS_ERR(data->regmap)) { in ltc4306_probe()
239 ret = PTR_ERR(data->regmap); in ltc4306_probe()
240 dev_err(&client->dev, "Failed to allocate register map: %d\n", in ltc4306_probe()
245 /* Reset and enable the mux if an enable GPIO is specified. */ in ltc4306_probe()
246 gpio = devm_gpiod_get_optional(&client->dev, "enable", GPIOD_OUT_LOW); in ltc4306_probe()
256 * Write the mux register at addr to verify in ltc4306_probe()
257 * that the mux is in fact present. This also in ltc4306_probe()
258 * initializes the mux to disconnected state. in ltc4306_probe()
260 if (regmap_write(data->regmap, LTC_REG_SWITCH, 0) < 0) { in ltc4306_probe()
261 dev_warn(&client->dev, "probe failed\n"); in ltc4306_probe()
262 return -ENODEV; in ltc4306_probe()
265 if (device_property_read_bool(&client->dev, in ltc4306_probe()
266 "ltc,downstream-accelerators-enable")) in ltc4306_probe()
269 if (device_property_read_bool(&client->dev, in ltc4306_probe()
270 "ltc,upstream-accelerators-enable")) in ltc4306_probe()
273 if (regmap_write(data->regmap, LTC_REG_CONFIG, val) < 0) in ltc4306_probe()
274 return -ENODEV; in ltc4306_probe()
281 for (num = 0; num < chip->nchans; num++) { in ltc4306_probe()
289 dev_info(&client->dev, in ltc4306_probe()
290 "registered %d multiplexed busses for I2C switch %s\n", in ltc4306_probe()
291 num, client->name); in ltc4306_probe()
316 MODULE_DESCRIPTION("Linear Technology LTC4306, LTC4305 I2C mux/switch driver");