diff options
Diffstat (limited to 'drivers/mfd/twl6040.c')
-rw-r--r-- | drivers/mfd/twl6040.c | 90 |
1 files changed, 28 insertions, 62 deletions
diff --git a/drivers/mfd/twl6040.c b/drivers/mfd/twl6040.c index c7df66a208d4..daf66942071c 100644 --- a/drivers/mfd/twl6040.c +++ b/drivers/mfd/twl6040.c | |||
@@ -44,17 +44,12 @@ | |||
44 | #define VIBRACTRL_MEMBER(reg) ((reg == TWL6040_REG_VIBCTLL) ? 0 : 1) | 44 | #define VIBRACTRL_MEMBER(reg) ((reg == TWL6040_REG_VIBCTLL) ? 0 : 1) |
45 | #define TWL6040_NUM_SUPPLIES (2) | 45 | #define TWL6040_NUM_SUPPLIES (2) |
46 | 46 | ||
47 | static bool twl6040_has_vibra(struct twl6040_platform_data *pdata, | 47 | static bool twl6040_has_vibra(struct device_node *node) |
48 | struct device_node *node) | ||
49 | { | 48 | { |
50 | if (pdata && pdata->vibra) | ||
51 | return true; | ||
52 | |||
53 | #ifdef CONFIG_OF | 49 | #ifdef CONFIG_OF |
54 | if (of_find_node_by_name(node, "vibra")) | 50 | if (of_find_node_by_name(node, "vibra")) |
55 | return true; | 51 | return true; |
56 | #endif | 52 | #endif |
57 | |||
58 | return false; | 53 | return false; |
59 | } | 54 | } |
60 | 55 | ||
@@ -537,14 +532,13 @@ static struct regmap_irq_chip twl6040_irq_chip = { | |||
537 | static int twl6040_probe(struct i2c_client *client, | 532 | static int twl6040_probe(struct i2c_client *client, |
538 | const struct i2c_device_id *id) | 533 | const struct i2c_device_id *id) |
539 | { | 534 | { |
540 | struct twl6040_platform_data *pdata = client->dev.platform_data; | ||
541 | struct device_node *node = client->dev.of_node; | 535 | struct device_node *node = client->dev.of_node; |
542 | struct twl6040 *twl6040; | 536 | struct twl6040 *twl6040; |
543 | struct mfd_cell *cell = NULL; | 537 | struct mfd_cell *cell = NULL; |
544 | int irq, ret, children = 0; | 538 | int irq, ret, children = 0; |
545 | 539 | ||
546 | if (!pdata && !node) { | 540 | if (!node) { |
547 | dev_err(&client->dev, "Platform data is missing\n"); | 541 | dev_err(&client->dev, "of node is missing\n"); |
548 | return -EINVAL; | 542 | return -EINVAL; |
549 | } | 543 | } |
550 | 544 | ||
@@ -556,23 +550,19 @@ static int twl6040_probe(struct i2c_client *client, | |||
556 | 550 | ||
557 | twl6040 = devm_kzalloc(&client->dev, sizeof(struct twl6040), | 551 | twl6040 = devm_kzalloc(&client->dev, sizeof(struct twl6040), |
558 | GFP_KERNEL); | 552 | GFP_KERNEL); |
559 | if (!twl6040) { | 553 | if (!twl6040) |
560 | ret = -ENOMEM; | 554 | return -ENOMEM; |
561 | goto err; | ||
562 | } | ||
563 | 555 | ||
564 | twl6040->regmap = devm_regmap_init_i2c(client, &twl6040_regmap_config); | 556 | twl6040->regmap = devm_regmap_init_i2c(client, &twl6040_regmap_config); |
565 | if (IS_ERR(twl6040->regmap)) { | 557 | if (IS_ERR(twl6040->regmap)) |
566 | ret = PTR_ERR(twl6040->regmap); | 558 | return PTR_ERR(twl6040->regmap); |
567 | goto err; | ||
568 | } | ||
569 | 559 | ||
570 | i2c_set_clientdata(client, twl6040); | 560 | i2c_set_clientdata(client, twl6040); |
571 | 561 | ||
572 | twl6040->supplies[0].supply = "vio"; | 562 | twl6040->supplies[0].supply = "vio"; |
573 | twl6040->supplies[1].supply = "v2v1"; | 563 | twl6040->supplies[1].supply = "v2v1"; |
574 | ret = devm_regulator_bulk_get(&client->dev, TWL6040_NUM_SUPPLIES, | 564 | ret = devm_regulator_bulk_get(&client->dev, TWL6040_NUM_SUPPLIES, |
575 | twl6040->supplies); | 565 | twl6040->supplies); |
576 | if (ret != 0) { | 566 | if (ret != 0) { |
577 | dev_err(&client->dev, "Failed to get supplies: %d\n", ret); | 567 | dev_err(&client->dev, "Failed to get supplies: %d\n", ret); |
578 | goto regulator_get_err; | 568 | goto regulator_get_err; |
@@ -593,44 +583,40 @@ static int twl6040_probe(struct i2c_client *client, | |||
593 | twl6040->rev = twl6040_reg_read(twl6040, TWL6040_REG_ASICREV); | 583 | twl6040->rev = twl6040_reg_read(twl6040, TWL6040_REG_ASICREV); |
594 | 584 | ||
595 | /* ERRATA: Automatic power-up is not possible in ES1.0 */ | 585 | /* ERRATA: Automatic power-up is not possible in ES1.0 */ |
596 | if (twl6040_get_revid(twl6040) > TWL6040_REV_ES1_0) { | 586 | if (twl6040_get_revid(twl6040) > TWL6040_REV_ES1_0) |
597 | if (pdata) | 587 | twl6040->audpwron = of_get_named_gpio(node, |
598 | twl6040->audpwron = pdata->audpwron_gpio; | 588 | "ti,audpwron-gpio", 0); |
599 | else | 589 | else |
600 | twl6040->audpwron = of_get_named_gpio(node, | ||
601 | "ti,audpwron-gpio", 0); | ||
602 | } else | ||
603 | twl6040->audpwron = -EINVAL; | 590 | twl6040->audpwron = -EINVAL; |
604 | 591 | ||
605 | if (gpio_is_valid(twl6040->audpwron)) { | 592 | if (gpio_is_valid(twl6040->audpwron)) { |
606 | ret = devm_gpio_request_one(&client->dev, twl6040->audpwron, | 593 | ret = devm_gpio_request_one(&client->dev, twl6040->audpwron, |
607 | GPIOF_OUT_INIT_LOW, "audpwron"); | 594 | GPIOF_OUT_INIT_LOW, "audpwron"); |
608 | if (ret) | 595 | if (ret) |
609 | goto gpio_err; | 596 | goto gpio_err; |
610 | } | 597 | } |
611 | 598 | ||
612 | ret = regmap_add_irq_chip(twl6040->regmap, twl6040->irq, | 599 | ret = regmap_add_irq_chip(twl6040->regmap, twl6040->irq, IRQF_ONESHOT, |
613 | IRQF_ONESHOT, 0, &twl6040_irq_chip, | 600 | 0, &twl6040_irq_chip,&twl6040->irq_data); |
614 | &twl6040->irq_data); | ||
615 | if (ret < 0) | 601 | if (ret < 0) |
616 | goto gpio_err; | 602 | goto gpio_err; |
617 | 603 | ||
618 | twl6040->irq_ready = regmap_irq_get_virq(twl6040->irq_data, | 604 | twl6040->irq_ready = regmap_irq_get_virq(twl6040->irq_data, |
619 | TWL6040_IRQ_READY); | 605 | TWL6040_IRQ_READY); |
620 | twl6040->irq_th = regmap_irq_get_virq(twl6040->irq_data, | 606 | twl6040->irq_th = regmap_irq_get_virq(twl6040->irq_data, |
621 | TWL6040_IRQ_TH); | 607 | TWL6040_IRQ_TH); |
622 | 608 | ||
623 | ret = devm_request_threaded_irq(twl6040->dev, twl6040->irq_ready, NULL, | 609 | ret = devm_request_threaded_irq(twl6040->dev, twl6040->irq_ready, NULL, |
624 | twl6040_readyint_handler, IRQF_ONESHOT, | 610 | twl6040_readyint_handler, IRQF_ONESHOT, |
625 | "twl6040_irq_ready", twl6040); | 611 | "twl6040_irq_ready", twl6040); |
626 | if (ret) { | 612 | if (ret) { |
627 | dev_err(twl6040->dev, "READY IRQ request failed: %d\n", ret); | 613 | dev_err(twl6040->dev, "READY IRQ request failed: %d\n", ret); |
628 | goto readyirq_err; | 614 | goto readyirq_err; |
629 | } | 615 | } |
630 | 616 | ||
631 | ret = devm_request_threaded_irq(twl6040->dev, twl6040->irq_th, NULL, | 617 | ret = devm_request_threaded_irq(twl6040->dev, twl6040->irq_th, NULL, |
632 | twl6040_thint_handler, IRQF_ONESHOT, | 618 | twl6040_thint_handler, IRQF_ONESHOT, |
633 | "twl6040_irq_th", twl6040); | 619 | "twl6040_irq_th", twl6040); |
634 | if (ret) { | 620 | if (ret) { |
635 | dev_err(twl6040->dev, "Thermal IRQ request failed: %d\n", ret); | 621 | dev_err(twl6040->dev, "Thermal IRQ request failed: %d\n", ret); |
636 | goto thirq_err; | 622 | goto thirq_err; |
@@ -642,8 +628,6 @@ static int twl6040_probe(struct i2c_client *client, | |||
642 | /* | 628 | /* |
643 | * The main functionality of twl6040 to provide audio on OMAP4+ systems. | 629 | * The main functionality of twl6040 to provide audio on OMAP4+ systems. |
644 | * We can add the ASoC codec child whenever this driver has been loaded. | 630 | * We can add the ASoC codec child whenever this driver has been loaded. |
645 | * The ASoC codec can work without pdata, pass the platform_data only if | ||
646 | * it has been provided. | ||
647 | */ | 631 | */ |
648 | irq = regmap_irq_get_virq(twl6040->irq_data, TWL6040_IRQ_PLUG); | 632 | irq = regmap_irq_get_virq(twl6040->irq_data, TWL6040_IRQ_PLUG); |
649 | cell = &twl6040->cells[children]; | 633 | cell = &twl6040->cells[children]; |
@@ -652,13 +636,10 @@ static int twl6040_probe(struct i2c_client *client, | |||
652 | twl6040_codec_rsrc[0].end = irq; | 636 | twl6040_codec_rsrc[0].end = irq; |
653 | cell->resources = twl6040_codec_rsrc; | 637 | cell->resources = twl6040_codec_rsrc; |
654 | cell->num_resources = ARRAY_SIZE(twl6040_codec_rsrc); | 638 | cell->num_resources = ARRAY_SIZE(twl6040_codec_rsrc); |
655 | if (pdata && pdata->codec) { | ||
656 | cell->platform_data = pdata->codec; | ||
657 | cell->pdata_size = sizeof(*pdata->codec); | ||
658 | } | ||
659 | children++; | 639 | children++; |
660 | 640 | ||
661 | if (twl6040_has_vibra(pdata, node)) { | 641 | /* Vibra input driver support */ |
642 | if (twl6040_has_vibra(node)) { | ||
662 | irq = regmap_irq_get_virq(twl6040->irq_data, TWL6040_IRQ_VIB); | 643 | irq = regmap_irq_get_virq(twl6040->irq_data, TWL6040_IRQ_VIB); |
663 | 644 | ||
664 | cell = &twl6040->cells[children]; | 645 | cell = &twl6040->cells[children]; |
@@ -667,28 +648,13 @@ static int twl6040_probe(struct i2c_client *client, | |||
667 | twl6040_vibra_rsrc[0].end = irq; | 648 | twl6040_vibra_rsrc[0].end = irq; |
668 | cell->resources = twl6040_vibra_rsrc; | 649 | cell->resources = twl6040_vibra_rsrc; |
669 | cell->num_resources = ARRAY_SIZE(twl6040_vibra_rsrc); | 650 | cell->num_resources = ARRAY_SIZE(twl6040_vibra_rsrc); |
670 | |||
671 | if (pdata && pdata->vibra) { | ||
672 | cell->platform_data = pdata->vibra; | ||
673 | cell->pdata_size = sizeof(*pdata->vibra); | ||
674 | } | ||
675 | children++; | 651 | children++; |
676 | } | 652 | } |
677 | 653 | ||
678 | /* | 654 | /* GPO support */ |
679 | * Enable the GPO driver in the following cases: | 655 | cell = &twl6040->cells[children]; |
680 | * DT booted kernel or legacy boot with valid gpo platform_data | 656 | cell->name = "twl6040-gpo"; |
681 | */ | 657 | children++; |
682 | if (!pdata || (pdata && pdata->gpo)) { | ||
683 | cell = &twl6040->cells[children]; | ||
684 | cell->name = "twl6040-gpo"; | ||
685 | |||
686 | if (pdata) { | ||
687 | cell->platform_data = pdata->gpo; | ||
688 | cell->pdata_size = sizeof(*pdata->gpo); | ||
689 | } | ||
690 | children++; | ||
691 | } | ||
692 | 658 | ||
693 | ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children, | 659 | ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children, |
694 | NULL, 0, NULL); | 660 | NULL, 0, NULL); |
@@ -707,7 +673,7 @@ gpio_err: | |||
707 | regulator_bulk_disable(TWL6040_NUM_SUPPLIES, twl6040->supplies); | 673 | regulator_bulk_disable(TWL6040_NUM_SUPPLIES, twl6040->supplies); |
708 | regulator_get_err: | 674 | regulator_get_err: |
709 | i2c_set_clientdata(client, NULL); | 675 | i2c_set_clientdata(client, NULL); |
710 | err: | 676 | |
711 | return ret; | 677 | return ret; |
712 | } | 678 | } |
713 | 679 | ||