Lines Matching +full:gpo +full:- +full:config +full:- +full:1

1 // SPDX-License-Identifier: GPL-2.0-only
27 #define VIBRACTRL_MEMBER(reg) ((reg == TWL6040_REG_VIBCTLL) ? 0 : 1)
79 TWL6040_I2CSEL | TWL6040_INTCLRMODE | TWL6040_I2CMODE(1) },
101 ret = regmap_read(twl6040->regmap, reg, &val); in twl6040_reg_read()
113 ret = regmap_write(twl6040->regmap, reg, val); in twl6040_reg_write()
121 return regmap_update_bits(twl6040->regmap, reg, mask, mask); in twl6040_set_bits()
127 return regmap_update_bits(twl6040->regmap, reg, mask, 0); in twl6040_clear_bits()
131 /* twl6040 codec manual power-up sequence */
137 /* enable high-side LDO, reference system and internal oscillator */ in twl6040_power_up_manual()
151 /* enable low-side LDO */ in twl6040_power_up_manual()
158 /* enable low-power PLL */ in twl6040_power_up_manual()
186 dev_err(twl6040->dev, "manual power-up failed\n"); in twl6040_power_up_manual()
190 /* twl6040 manual power-down sequence */
204 /* disable low-power PLL */ in twl6040_power_down_manual()
208 /* disable low-side LDO */ in twl6040_power_down_manual()
216 /* disable high-side LDO, reference system and internal oscillator */ in twl6040_power_down_manual()
225 complete(&twl6040->ready); in twl6040_readyint_handler()
237 dev_warn(twl6040->dev, "Thermal shutdown, powering-off"); in twl6040_thint_handler()
240 dev_warn(twl6040->dev, "Leaving thermal shutdown, powering-on"); in twl6040_thint_handler()
241 twl6040_power(twl6040, 1); in twl6040_thint_handler()
251 gpiod_set_value_cansleep(twl6040->audpwron, 1); in twl6040_power_up_automatic()
253 time_left = wait_for_completion_timeout(&twl6040->ready, in twl6040_power_up_automatic()
258 dev_warn(twl6040->dev, "timeout waiting for READYINT\n"); in twl6040_power_up_automatic()
261 dev_err(twl6040->dev, "automatic power-up failed\n"); in twl6040_power_up_automatic()
262 gpiod_set_value_cansleep(twl6040->audpwron, 0); in twl6040_power_up_automatic()
263 return -ETIMEDOUT; in twl6040_power_up_automatic()
274 mutex_lock(&twl6040->mutex); in twl6040_power()
277 /* already powered-up */ in twl6040_power()
278 if (twl6040->power_count++) in twl6040_power()
281 ret = clk_prepare_enable(twl6040->clk32k); in twl6040_power()
283 twl6040->power_count = 0; in twl6040_power()
288 regcache_cache_only(twl6040->regmap, false); in twl6040_power()
290 if (twl6040->audpwron) { in twl6040_power()
291 /* use automatic power-up sequence */ in twl6040_power()
294 clk_disable_unprepare(twl6040->clk32k); in twl6040_power()
295 twl6040->power_count = 0; in twl6040_power()
299 /* use manual power-up sequence */ in twl6040_power()
302 clk_disable_unprepare(twl6040->clk32k); in twl6040_power()
303 twl6040->power_count = 0; in twl6040_power()
309 * Register access can produce errors after power-up unless we in twl6040_power()
315 ret = regcache_sync(twl6040->regmap); in twl6040_power()
317 dev_err(twl6040->dev, "Failed to sync with the HW: %i\n", in twl6040_power()
323 twl6040->pll = TWL6040_SYSCLK_SEL_LPPLL; in twl6040_power()
324 twl6040->sysclk_rate = 19200000; in twl6040_power()
326 /* already powered-down */ in twl6040_power()
327 if (!twl6040->power_count) { in twl6040_power()
328 dev_err(twl6040->dev, in twl6040_power()
329 "device is already powered-off\n"); in twl6040_power()
330 ret = -EPERM; in twl6040_power()
334 if (--twl6040->power_count) in twl6040_power()
337 if (twl6040->audpwron) { in twl6040_power()
339 gpiod_set_value_cansleep(twl6040->audpwron, 0); in twl6040_power()
341 /* power-down sequence latency */ in twl6040_power()
344 /* use manual power-down sequence */ in twl6040_power()
349 regcache_cache_only(twl6040->regmap, true); in twl6040_power()
350 regcache_mark_dirty(twl6040->regmap); in twl6040_power()
352 twl6040->sysclk_rate = 0; in twl6040_power()
354 if (twl6040->pll == TWL6040_SYSCLK_SEL_HPPLL) { in twl6040_power()
355 clk_disable_unprepare(twl6040->mclk); in twl6040_power()
356 twl6040->mclk_rate = 0; in twl6040_power()
359 clk_disable_unprepare(twl6040->clk32k); in twl6040_power()
363 mutex_unlock(&twl6040->mutex); in twl6040_power()
374 mutex_lock(&twl6040->mutex); in twl6040_set_pll()
380 if (pll_id != twl6040->pll) { in twl6040_set_pll()
381 twl6040->sysclk_rate = 0; in twl6040_set_pll()
382 twl6040->mclk_rate = 0; in twl6040_set_pll()
387 /* low-power PLL divider */ in twl6040_set_pll()
389 if (twl6040->sysclk_rate != freq_out) { in twl6040_set_pll()
398 dev_err(twl6040->dev, in twl6040_set_pll()
401 ret = -EINVAL; in twl6040_set_pll()
409 if (twl6040->pll == pll_id) in twl6040_set_pll()
426 dev_err(twl6040->dev, in twl6040_set_pll()
428 ret = -EINVAL; in twl6040_set_pll()
432 clk_disable_unprepare(twl6040->mclk); in twl6040_set_pll()
435 /* high-performance PLL can provide only 19.2 MHz */ in twl6040_set_pll()
437 dev_err(twl6040->dev, in twl6040_set_pll()
439 ret = -EINVAL; in twl6040_set_pll()
443 if (twl6040->mclk_rate != freq_in) { in twl6040_set_pll()
468 dev_err(twl6040->dev, in twl6040_set_pll()
470 ret = -EINVAL; in twl6040_set_pll()
475 if (pll_id != twl6040->pll) in twl6040_set_pll()
476 clk_prepare_enable(twl6040->mclk); in twl6040_set_pll()
493 twl6040->mclk_rate = freq_in; in twl6040_set_pll()
497 dev_err(twl6040->dev, "unknown pll id %d\n", pll_id); in twl6040_set_pll()
498 ret = -EINVAL; in twl6040_set_pll()
502 twl6040->sysclk_rate = freq_out; in twl6040_set_pll()
503 twl6040->pll = pll_id; in twl6040_set_pll()
506 mutex_unlock(&twl6040->mutex); in twl6040_set_pll()
513 if (twl6040->power_count) in twl6040_get_pll()
514 return twl6040->pll; in twl6040_get_pll()
516 return -ENODEV; in twl6040_get_pll()
522 return twl6040->sysclk_rate; in twl6040_get_sysclk()
533 ret = regmap_read(twl6040->regmap, TWL6040_REG_VIBCTLL, &reg); in twl6040_get_vibralr_status()
538 ret = regmap_read(twl6040->regmap, TWL6040_REG_VIBCTLR, &reg); in twl6040_get_vibralr_status()
628 .num_regs = 1,
635 struct device_node *node = client->dev.of_node; in twl6040_probe()
641 dev_err(&client->dev, "of node is missing\n"); in twl6040_probe()
642 return -EINVAL; in twl6040_probe()
645 /* In order to operate correctly we need valid interrupt config */ in twl6040_probe()
646 if (!client->irq) { in twl6040_probe()
647 dev_err(&client->dev, "Invalid IRQ configuration\n"); in twl6040_probe()
648 return -EINVAL; in twl6040_probe()
651 twl6040 = devm_kzalloc(&client->dev, sizeof(struct twl6040), in twl6040_probe()
654 return -ENOMEM; in twl6040_probe()
656 twl6040->regmap = devm_regmap_init_i2c(client, &twl6040_regmap_config); in twl6040_probe()
657 if (IS_ERR(twl6040->regmap)) in twl6040_probe()
658 return PTR_ERR(twl6040->regmap); in twl6040_probe()
662 twl6040->clk32k = devm_clk_get(&client->dev, "clk32k"); in twl6040_probe()
663 if (IS_ERR(twl6040->clk32k)) { in twl6040_probe()
664 if (PTR_ERR(twl6040->clk32k) == -EPROBE_DEFER) in twl6040_probe()
665 return -EPROBE_DEFER; in twl6040_probe()
666 dev_dbg(&client->dev, "clk32k is not handled\n"); in twl6040_probe()
667 twl6040->clk32k = NULL; in twl6040_probe()
670 twl6040->mclk = devm_clk_get(&client->dev, "mclk"); in twl6040_probe()
671 if (IS_ERR(twl6040->mclk)) { in twl6040_probe()
672 if (PTR_ERR(twl6040->mclk) == -EPROBE_DEFER) in twl6040_probe()
673 return -EPROBE_DEFER; in twl6040_probe()
674 dev_dbg(&client->dev, "mclk is not handled\n"); in twl6040_probe()
675 twl6040->mclk = NULL; in twl6040_probe()
678 twl6040->supplies[0].supply = "vio"; in twl6040_probe()
679 twl6040->supplies[1].supply = "v2v1"; in twl6040_probe()
680 ret = devm_regulator_bulk_get(&client->dev, TWL6040_NUM_SUPPLIES, in twl6040_probe()
681 twl6040->supplies); in twl6040_probe()
683 dev_err(&client->dev, "Failed to get supplies: %d\n", ret); in twl6040_probe()
687 ret = regulator_bulk_enable(TWL6040_NUM_SUPPLIES, twl6040->supplies); in twl6040_probe()
689 dev_err(&client->dev, "Failed to enable supplies: %d\n", ret); in twl6040_probe()
693 twl6040->dev = &client->dev; in twl6040_probe()
694 twl6040->irq = client->irq; in twl6040_probe()
696 mutex_init(&twl6040->mutex); in twl6040_probe()
697 init_completion(&twl6040->ready); in twl6040_probe()
699 regmap_register_patch(twl6040->regmap, twl6040_patch, in twl6040_probe()
702 twl6040->rev = twl6040_reg_read(twl6040, TWL6040_REG_ASICREV); in twl6040_probe()
703 if (twl6040->rev < 0) { in twl6040_probe()
704 dev_err(&client->dev, "Failed to read revision register: %d\n", in twl6040_probe()
705 twl6040->rev); in twl6040_probe()
706 ret = twl6040->rev; in twl6040_probe()
710 /* ERRATA: Automatic power-up is not possible in ES1.0 */ in twl6040_probe()
712 twl6040->audpwron = devm_gpiod_get_optional(&client->dev, in twl6040_probe()
715 ret = PTR_ERR_OR_ZERO(twl6040->audpwron); in twl6040_probe()
719 gpiod_set_consumer_name(twl6040->audpwron, "audpwron"); in twl6040_probe()
725 ret = regmap_add_irq_chip(twl6040->regmap, twl6040->irq, IRQF_ONESHOT, in twl6040_probe()
726 0, &twl6040_irq_chip, &twl6040->irq_data); in twl6040_probe()
730 twl6040->irq_ready = regmap_irq_get_virq(twl6040->irq_data, in twl6040_probe()
732 twl6040->irq_th = regmap_irq_get_virq(twl6040->irq_data, in twl6040_probe()
735 ret = devm_request_threaded_irq(twl6040->dev, twl6040->irq_ready, NULL, in twl6040_probe()
739 dev_err(twl6040->dev, "READY IRQ request failed: %d\n", ret); in twl6040_probe()
743 ret = devm_request_threaded_irq(twl6040->dev, twl6040->irq_th, NULL, in twl6040_probe()
747 dev_err(twl6040->dev, "Thermal IRQ request failed: %d\n", ret); in twl6040_probe()
755 irq = regmap_irq_get_virq(twl6040->irq_data, TWL6040_IRQ_PLUG); in twl6040_probe()
756 cell = &twl6040->cells[children]; in twl6040_probe()
757 cell->name = "twl6040-codec"; in twl6040_probe()
760 cell->resources = twl6040_codec_rsrc; in twl6040_probe()
761 cell->num_resources = ARRAY_SIZE(twl6040_codec_rsrc); in twl6040_probe()
766 irq = regmap_irq_get_virq(twl6040->irq_data, TWL6040_IRQ_VIB); in twl6040_probe()
768 cell = &twl6040->cells[children]; in twl6040_probe()
769 cell->name = "twl6040-vibra"; in twl6040_probe()
772 cell->resources = twl6040_vibra_rsrc; in twl6040_probe()
773 cell->num_resources = ARRAY_SIZE(twl6040_vibra_rsrc); in twl6040_probe()
777 /* GPO support */ in twl6040_probe()
778 cell = &twl6040->cells[children]; in twl6040_probe()
779 cell->name = "twl6040-gpo"; in twl6040_probe()
783 cell = &twl6040->cells[children]; in twl6040_probe()
784 cell->name = "twl6040-pdmclk"; in twl6040_probe()
788 regcache_cache_only(twl6040->regmap, true); in twl6040_probe()
789 regcache_mark_dirty(twl6040->regmap); in twl6040_probe()
791 ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children, in twl6040_probe()
799 regmap_del_irq_chip(twl6040->irq, twl6040->irq_data); in twl6040_probe()
801 regulator_bulk_disable(TWL6040_NUM_SUPPLIES, twl6040->supplies); in twl6040_probe()
809 if (twl6040->power_count) in twl6040_remove()
812 regmap_del_irq_chip(twl6040->irq, twl6040->irq_data); in twl6040_remove()
814 mfd_remove_devices(&client->dev); in twl6040_remove()
816 regulator_bulk_disable(TWL6040_NUM_SUPPLIES, twl6040->supplies); in twl6040_remove()