Lines Matching +full:i2c +full:- +full:atr
1 // SPDX-License-Identifier: GPL-2.0-only
3 * ti_fpc202.c - FPC202 Dual Port Controller driver
11 #include <linux/i2c.h>
12 #include <linux/i2c-atr.h>
54 * So just set an invalid I2C address as the translation target when no client
64 struct i2c_atr *atr; member
84 * There is a predefined list of aliases for each FPC202 I2C in fpc202_fill_alias_table()
85 * self-address. This allows daisy-chained FPC202 units to in fpc202_fill_alias_table()
89 first_alias = 0x10 + 4 * port_id + 8 * ((u16)client->addr - 2); in fpc202_fill_alias_table()
104 val = i2c_smbus_read_byte_data(priv->client, reg); in fpc202_read()
110 return i2c_smbus_write_byte_data(priv->client, reg, value); in fpc202_write()
115 if (!priv->en_gpio) in fpc202_set_enable()
118 gpiod_set_value(priv->en_gpio, enable); in fpc202_set_enable()
130 dev_err(&priv->client->dev, "Failed to set GPIO %d value! err %d\n", offset, ret); in fpc202_gpio_set()
137 val |= BIT(offset - FPC202_GPIO_P0_S0_OUT_A); in fpc202_gpio_set()
139 val &= ~BIT(offset - FPC202_GPIO_P0_S0_OUT_A); in fpc202_gpio_set()
155 bit = BIT(offset - FPC202_GPIO_P0_S0_IN_B); in fpc202_gpio_get()
158 bit = BIT(offset - FPC202_GPIO_P0_S0_OUT_A); in fpc202_gpio_get()
171 return -EINVAL; in fpc202_gpio_direction_input()
184 return -EINVAL; in fpc202_gpio_direction_output()
192 val = (u8)ret | BIT(offset - FPC202_GPIO_P0_S0_OUT_A); in fpc202_gpio_direction_output()
201 * device numbers 0 and 1. If one of these aliases is found in an incoming I2C
210 guard(mutex)(&priv->reg_dev_lock); in fpc202_write_dev_addr()
227 priv->addr_caches[port_id][dev_num] = val; in fpc202_write_dev_addr()
232 static int fpc202_attach_addr(struct i2c_atr *atr, u32 chan_id, in fpc202_attach_addr() argument
235 struct fpc202_priv *priv = i2c_atr_get_driver_data(atr); in fpc202_attach_addr()
237 dev_dbg(&priv->client->dev, "attaching address 0x%02x to alias 0x%02x\n", addr, alias); in fpc202_attach_addr()
242 static void fpc202_detach_addr(struct i2c_atr *atr, u32 chan_id, in fpc202_detach_addr() argument
245 struct fpc202_priv *priv = i2c_atr_get_driver_data(atr); in fpc202_detach_addr()
251 mutex_lock(&priv->reg_dev_lock); in fpc202_detach_addr()
253 val = priv->addr_caches[chan_id][dev_num]; in fpc202_detach_addr()
255 mutex_unlock(&priv->reg_dev_lock); in fpc202_detach_addr()
258 dev_err(&priv->client->dev, "failed to read register 0x%x while detaching address 0x%02x\n", in fpc202_detach_addr()
278 struct device *dev = &priv->client->dev; in fpc202_probe_port()
287 fpc202_fill_alias_table(priv->client, aliases, port_id); in fpc202_probe_port()
290 ret = i2c_atr_add_adapter(priv->atr, &desc); in fpc202_probe_port()
294 set_bit(port_id, priv->probed_ports); in fpc202_probe_port()
305 i2c_atr_del_adapter(priv->atr, port_id); in fpc202_remove_port()
306 clear_bit(port_id, priv->probed_ports); in fpc202_remove_port()
311 struct device *dev = &client->dev; in fpc202_probe()
318 return -ENOMEM; in fpc202_probe()
320 mutex_init(&priv->reg_dev_lock); in fpc202_probe()
322 priv->client = client; in fpc202_probe()
325 priv->en_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_HIGH); in fpc202_probe()
326 if (IS_ERR(priv->en_gpio)) { in fpc202_probe()
327 ret = PTR_ERR(priv->en_gpio); in fpc202_probe()
332 priv->gpio.label = "gpio-fpc202"; in fpc202_probe()
333 priv->gpio.base = -1; in fpc202_probe()
334 priv->gpio.direction_input = fpc202_gpio_direction_input; in fpc202_probe()
335 priv->gpio.direction_output = fpc202_gpio_direction_output; in fpc202_probe()
336 priv->gpio.set = fpc202_gpio_set; in fpc202_probe()
337 priv->gpio.get = fpc202_gpio_get; in fpc202_probe()
338 priv->gpio.ngpio = FPC202_GPIO_COUNT; in fpc202_probe()
339 priv->gpio.parent = dev; in fpc202_probe()
340 priv->gpio.owner = THIS_MODULE; in fpc202_probe()
342 ret = gpiochip_add_data(&priv->gpio, priv); in fpc202_probe()
344 priv->gpio.parent = NULL; in fpc202_probe()
349 priv->atr = i2c_atr_new(client->adapter, dev, &fpc202_atr_ops, 2, 0); in fpc202_probe()
350 if (IS_ERR(priv->atr)) { in fpc202_probe()
351 ret = PTR_ERR(priv->atr); in fpc202_probe()
352 dev_err(dev, "failed to create i2c atr err %d\n", ret); in fpc202_probe()
356 i2c_atr_set_driver_data(priv->atr, priv); in fpc202_probe()
358 bitmap_zero(priv->probed_ports, FPC202_NUM_PORTS); in fpc202_probe()
360 for_each_child_of_node(dev->of_node, i2c_handle) { in fpc202_probe()
363 if (ret == -EINVAL) in fpc202_probe()
372 ret = -EINVAL; in fpc202_probe()
386 for_each_set_bit(port_id, priv->probed_ports, FPC202_NUM_PORTS) in fpc202_probe()
389 i2c_atr_delete(priv->atr); in fpc202_probe()
392 gpiochip_remove(&priv->gpio); in fpc202_probe()
394 mutex_destroy(&priv->reg_dev_lock); in fpc202_probe()
404 for_each_set_bit(port_id, priv->probed_ports, FPC202_NUM_PORTS) in fpc202_remove()
407 mutex_destroy(&priv->reg_dev_lock); in fpc202_remove()
409 i2c_atr_delete(priv->atr); in fpc202_remove()
412 gpiochip_remove(&priv->gpio); in fpc202_remove()