Lines Matching full:stmfx

3  * Driver for STMicroelectronics Multi-Function eXpander (STMFX) core
13 #include <linux/mfd/stmfx.h>
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",
116 int stmfx_function_enable(struct stmfx *stmfx, u32 func) in stmfx_function_enable() argument
122 ret = regmap_read(stmfx->map, STMFX_REG_SYS_CTRL, &sys_ctrl); in stmfx_function_enable()
127 * IDD and TS have priority in STMFX FW, so if IDD and TS are enabled, in stmfx_function_enable()
128 * ALTGPIO function is disabled by STMFX FW. If IDD or TS is enabled, in stmfx_function_enable()
134 dev_err(stmfx->dev, "ALTGPIO function already enabled\n"); in stmfx_function_enable()
141 dev_err(stmfx->dev, "TS in use, aGPIO[3:0] unavailable\n"); in stmfx_function_enable()
148 dev_err(stmfx->dev, "IDD in use, aGPIO[7:4] unavailable\n"); 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() argument
162 return regmap_update_bits(stmfx->map, STMFX_REG_SYS_CTRL, mask, 0); in stmfx_function_disable()
168 struct stmfx *stmfx = irq_data_get_irq_chip_data(data); in stmfx_irq_bus_lock() local
170 mutex_lock(&stmfx->lock); in stmfx_irq_bus_lock()
175 struct stmfx *stmfx = irq_data_get_irq_chip_data(data); in stmfx_irq_bus_sync_unlock() local
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()
184 struct stmfx *stmfx = irq_data_get_irq_chip_data(data); in stmfx_irq_mask() local
186 stmfx->irq_src &= ~BIT(data->hwirq % 8); in stmfx_irq_mask()
191 struct stmfx *stmfx = irq_data_get_irq_chip_data(data); in stmfx_irq_unmask() local
193 stmfx->irq_src |= BIT(data->hwirq % 8); in stmfx_irq_unmask()
197 .name = "stmfx-core",
206 struct stmfx *stmfx = data; in stmfx_irq_handler() local
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()
257 struct stmfx *stmfx = i2c_get_clientdata(client); in stmfx_irq_exit() local
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()
268 struct stmfx *stmfx = i2c_get_clientdata(client); in stmfx_irq_init() local
272 stmfx->irq_domain = irq_domain_add_simple(stmfx->dev->of_node, in stmfx_irq_init()
274 &stmfx_irq_ops, stmfx); 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()
280 if (!of_property_read_bool(stmfx->dev->of_node, "drive-open-drain")) 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()
295 "stmfx", stmfx); 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() argument
313 ret = regmap_write(stmfx->map, STMFX_REG_SYS_CTRL, in stmfx_chip_reset()
325 struct stmfx *stmfx = i2c_get_clientdata(client); in stmfx_chip_init() local
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()
338 if (stmfx->vdd) { in stmfx_chip_init()
339 ret = regulator_enable(stmfx->vdd); in stmfx_chip_init()
346 ret = regmap_read(stmfx->map, STMFX_REG_CHIP_ID, &id); in stmfx_chip_init()
354 * STMFX I2C address follows the 7-bit format (MSB), that's why in stmfx_chip_init()
357 * STMFX_I2C_ADDR| STMFX | Linux in stmfx_chip_init()
369 ret = regmap_bulk_read(stmfx->map, STMFX_REG_FW_VERSION_MSB, in stmfx_chip_init()
376 dev_info(&client->dev, "STMFX id: %#x, fw version: %x.%02x\n", in stmfx_chip_init()
379 ret = stmfx_chip_reset(stmfx); in stmfx_chip_init()
388 if (stmfx->vdd) in stmfx_chip_init()
389 regulator_disable(stmfx->vdd); in stmfx_chip_init()
396 struct stmfx *stmfx = i2c_get_clientdata(client); in stmfx_chip_exit() local
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()
404 ret = regulator_disable(stmfx->vdd); in stmfx_chip_exit()
415 struct stmfx *stmfx; in stmfx_probe() local
418 stmfx = devm_kzalloc(dev, sizeof(*stmfx), GFP_KERNEL); in stmfx_probe()
419 if (!stmfx) in stmfx_probe()
422 i2c_set_clientdata(client, stmfx); 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()
433 mutex_init(&stmfx->lock); in stmfx_probe()
454 0, stmfx->irq_domain); in stmfx_probe()
477 struct stmfx *stmfx = dev_get_drvdata(dev); in stmfx_suspend() local
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()
501 struct stmfx *stmfx = dev_get_drvdata(dev); in stmfx_resume() local
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()
514 ret = stmfx_chip_reset(stmfx); 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",
560 MODULE_DESCRIPTION("STMFX core driver");