Lines Matching +full:int +full:- +full:map +full:- +full:mask

1 // SPDX-License-Identifier: GPL-2.0
3 * Driver for STMicroelectronics Multi-Function eXpander (STMFX) core
17 static bool stmfx_reg_volatile(struct device *dev, unsigned int reg) in stmfx_reg_volatile()
44 static bool stmfx_reg_writeable(struct device *dev, unsigned int reg) in stmfx_reg_writeable()
78 .of_compatible = "st,stmfx-0300-pinctrl",
79 .name = "stmfx-pinctrl",
84 .of_compatible = "st,stmfx-0300-idd",
85 .name = "stmfx-idd",
90 .of_compatible = "st,stmfx-0300-ts",
91 .name = "stmfx-ts",
99 u8 mask = 0; in stmfx_func_to_mask() local
102 mask |= STMFX_REG_SYS_CTRL_GPIO_EN; in stmfx_func_to_mask()
105 mask |= STMFX_REG_SYS_CTRL_ALTGPIO_EN; in stmfx_func_to_mask()
108 mask |= STMFX_REG_SYS_CTRL_TS_EN; in stmfx_func_to_mask()
111 mask |= STMFX_REG_SYS_CTRL_IDD_EN; in stmfx_func_to_mask()
113 return mask; in stmfx_func_to_mask()
116 int stmfx_function_enable(struct stmfx *stmfx, u32 func) in stmfx_function_enable()
119 u8 mask; in stmfx_function_enable() local
120 int ret; in stmfx_function_enable()
122 ret = regmap_read(stmfx->map, STMFX_REG_SYS_CTRL, &sys_ctrl); in stmfx_function_enable()
134 dev_err(stmfx->dev, "ALTGPIO function already enabled\n"); in stmfx_function_enable()
135 return -EBUSY; in stmfx_function_enable()
141 dev_err(stmfx->dev, "TS in use, aGPIO[3:0] unavailable\n"); in stmfx_function_enable()
142 return -EBUSY; in stmfx_function_enable()
148 dev_err(stmfx->dev, "IDD in use, aGPIO[7:4] unavailable\n"); in stmfx_function_enable()
149 return -EBUSY; in stmfx_function_enable()
152 mask = stmfx_func_to_mask(func); in stmfx_function_enable()
154 return regmap_update_bits(stmfx->map, STMFX_REG_SYS_CTRL, mask, mask); in stmfx_function_enable()
158 int stmfx_function_disable(struct stmfx *stmfx, u32 func) in stmfx_function_disable()
160 u8 mask = stmfx_func_to_mask(func); in stmfx_function_disable() local
162 return regmap_update_bits(stmfx->map, STMFX_REG_SYS_CTRL, mask, 0); in stmfx_function_disable()
170 mutex_lock(&stmfx->lock); in stmfx_irq_bus_lock()
177 regmap_write(stmfx->map, STMFX_REG_IRQ_SRC_EN, stmfx->irq_src); in stmfx_irq_bus_sync_unlock()
179 mutex_unlock(&stmfx->lock); in stmfx_irq_bus_sync_unlock()
186 stmfx->irq_src &= ~BIT(data->hwirq % 8); in stmfx_irq_mask()
193 stmfx->irq_src |= BIT(data->hwirq % 8); in stmfx_irq_unmask()
197 .name = "stmfx-core",
204 static irqreturn_t stmfx_irq_handler(int irq, void *data) in stmfx_irq_handler()
209 int n, ret; in stmfx_irq_handler()
211 ret = regmap_read(stmfx->map, STMFX_REG_IRQ_PENDING, &pending); in stmfx_irq_handler()
221 ret = regmap_write(stmfx->map, STMFX_REG_IRQ_ACK, ack); in stmfx_irq_handler()
228 handle_nested_irq(irq_find_mapping(stmfx->irq_domain, n)); in stmfx_irq_handler()
233 static int stmfx_irq_map(struct irq_domain *d, unsigned int virq, in stmfx_irq_map()
236 irq_set_chip_data(virq, d->host_data); in stmfx_irq_map()
244 static void stmfx_irq_unmap(struct irq_domain *d, unsigned int virq) in stmfx_irq_unmap()
251 .map = stmfx_irq_map,
258 int hwirq; in stmfx_irq_exit()
261 irq_dispose_mapping(irq_find_mapping(stmfx->irq_domain, hwirq)); in stmfx_irq_exit()
263 irq_domain_remove(stmfx->irq_domain); in stmfx_irq_exit()
266 static int stmfx_irq_init(struct i2c_client *client) in stmfx_irq_init()
270 int ret; in stmfx_irq_init()
272 stmfx->irq_domain = irq_domain_add_simple(stmfx->dev->of_node, in stmfx_irq_init()
275 if (!stmfx->irq_domain) { in stmfx_irq_init()
276 dev_err(stmfx->dev, "Failed to create IRQ domain\n"); in stmfx_irq_init()
277 return -EINVAL; in stmfx_irq_init()
280 if (!of_property_read_bool(stmfx->dev->of_node, "drive-open-drain")) in stmfx_irq_init()
283 irqtrigger = irq_get_trigger_type(client->irq); in stmfx_irq_init()
288 ret = regmap_write(stmfx->map, STMFX_REG_IRQ_OUT_PIN, irqoutpin); in stmfx_irq_init()
292 ret = devm_request_threaded_irq(stmfx->dev, client->irq, in stmfx_irq_init()
299 stmfx->irq = client->irq; in stmfx_irq_init()
309 static int stmfx_chip_reset(struct stmfx *stmfx) in stmfx_chip_reset()
311 int ret; in stmfx_chip_reset()
313 ret = regmap_write(stmfx->map, STMFX_REG_SYS_CTRL, in stmfx_chip_reset()
323 static int stmfx_chip_init(struct i2c_client *client) in stmfx_chip_init()
328 int ret; in stmfx_chip_init()
330 stmfx->vdd = devm_regulator_get_optional(&client->dev, "vdd"); in stmfx_chip_init()
331 ret = PTR_ERR_OR_ZERO(stmfx->vdd); in stmfx_chip_init()
333 stmfx->vdd = NULL; in stmfx_chip_init()
334 if (ret != -ENODEV) in stmfx_chip_init()
335 return dev_err_probe(&client->dev, ret, "Failed to get VDD regulator\n"); in stmfx_chip_init()
338 if (stmfx->vdd) { in stmfx_chip_init()
339 ret = regulator_enable(stmfx->vdd); in stmfx_chip_init()
341 dev_err(&client->dev, "VDD enable failed: %d\n", ret); in stmfx_chip_init()
346 ret = regmap_read(stmfx->map, STMFX_REG_CHIP_ID, &id); in stmfx_chip_init()
348 dev_err(&client->dev, "Error reading chip ID: %d\n", ret); in stmfx_chip_init()
354 * STMFX I2C address follows the 7-bit format (MSB), that's why in stmfx_chip_init()
355 * client->addr is shifted. in stmfx_chip_init()
359 *--------------------------------------------------------- in stmfx_chip_init()
363 if (FIELD_GET(STMFX_REG_CHIP_ID_MASK, ~id) != (client->addr << 1)) { in stmfx_chip_init()
364 dev_err(&client->dev, "Unknown chip ID: %#x\n", id); in stmfx_chip_init()
365 ret = -EINVAL; in stmfx_chip_init()
369 ret = regmap_bulk_read(stmfx->map, STMFX_REG_FW_VERSION_MSB, in stmfx_chip_init()
372 dev_err(&client->dev, "Error reading FW version: %d\n", ret); in stmfx_chip_init()
376 dev_info(&client->dev, "STMFX id: %#x, fw version: %x.%02x\n", in stmfx_chip_init()
381 dev_err(&client->dev, "Failed to reset chip: %d\n", ret); in stmfx_chip_init()
388 if (stmfx->vdd) in stmfx_chip_init()
389 regulator_disable(stmfx->vdd); in stmfx_chip_init()
398 regmap_write(stmfx->map, STMFX_REG_IRQ_SRC_EN, 0); in stmfx_chip_exit()
399 regmap_write(stmfx->map, STMFX_REG_SYS_CTRL, 0); in stmfx_chip_exit()
401 if (stmfx->vdd) { in stmfx_chip_exit()
402 int ret; in stmfx_chip_exit()
404 ret = regulator_disable(stmfx->vdd); in stmfx_chip_exit()
406 dev_err(&client->dev, in stmfx_chip_exit()
412 static int stmfx_probe(struct i2c_client *client) in stmfx_probe()
414 struct device *dev = &client->dev; in stmfx_probe()
416 int ret; in stmfx_probe()
420 return -ENOMEM; in stmfx_probe()
424 stmfx->dev = dev; in stmfx_probe()
426 stmfx->map = devm_regmap_init_i2c(client, &stmfx_regmap_config); in stmfx_probe()
427 if (IS_ERR(stmfx->map)) { in stmfx_probe()
428 ret = PTR_ERR(stmfx->map); in stmfx_probe()
429 dev_err(dev, "Failed to allocate register map: %d\n", ret); in stmfx_probe()
433 mutex_init(&stmfx->lock); in stmfx_probe()
437 if (ret == -ETIMEDOUT) in stmfx_probe()
438 return -EPROBE_DEFER; in stmfx_probe()
442 if (client->irq < 0) { in stmfx_probe()
443 dev_err(dev, "Failed to get IRQ: %d\n", client->irq); in stmfx_probe()
444 ret = client->irq; in stmfx_probe()
454 0, stmfx->irq_domain); in stmfx_probe()
475 static int stmfx_suspend(struct device *dev) in stmfx_suspend()
478 int ret; in stmfx_suspend()
480 ret = regmap_raw_read(stmfx->map, STMFX_REG_SYS_CTRL, in stmfx_suspend()
481 &stmfx->bkp_sysctrl, sizeof(stmfx->bkp_sysctrl)); in stmfx_suspend()
485 ret = regmap_raw_read(stmfx->map, STMFX_REG_IRQ_OUT_PIN, in stmfx_suspend()
486 &stmfx->bkp_irqoutpin, in stmfx_suspend()
487 sizeof(stmfx->bkp_irqoutpin)); in stmfx_suspend()
491 disable_irq(stmfx->irq); in stmfx_suspend()
493 if (stmfx->vdd) in stmfx_suspend()
494 return regulator_disable(stmfx->vdd); in stmfx_suspend()
499 static int stmfx_resume(struct device *dev) in stmfx_resume()
502 int ret; in stmfx_resume()
504 if (stmfx->vdd) { in stmfx_resume()
505 ret = regulator_enable(stmfx->vdd); in stmfx_resume()
507 dev_err(stmfx->dev, in stmfx_resume()
513 /* Reset STMFX - supply has been stopped during suspend */ in stmfx_resume()
516 dev_err(stmfx->dev, "Failed to reset chip: %d\n", ret); in stmfx_resume()
520 ret = regmap_raw_write(stmfx->map, STMFX_REG_SYS_CTRL, in stmfx_resume()
521 &stmfx->bkp_sysctrl, sizeof(stmfx->bkp_sysctrl)); in stmfx_resume()
525 ret = regmap_raw_write(stmfx->map, STMFX_REG_IRQ_OUT_PIN, in stmfx_resume()
526 &stmfx->bkp_irqoutpin, in stmfx_resume()
527 sizeof(stmfx->bkp_irqoutpin)); in stmfx_resume()
531 ret = regmap_raw_write(stmfx->map, STMFX_REG_IRQ_SRC_EN, in stmfx_resume()
532 &stmfx->irq_src, sizeof(stmfx->irq_src)); in stmfx_resume()
536 enable_irq(stmfx->irq); in stmfx_resume()
544 { .compatible = "st,stmfx-0300", },
551 .name = "stmfx-core",