| .. | .. |
|---|
| 29 | 29 | #include <linux/i2c.h> |
|---|
| 30 | 30 | #include <linux/delay.h> |
|---|
| 31 | 31 | #include <linux/regulator/consumer.h> |
|---|
| 32 | +#include <linux/gpio/consumer.h> |
|---|
| 32 | 33 | #include <linux/of_device.h> |
|---|
| 33 | | -#include <linux/of_gpio.h> |
|---|
| 34 | 34 | |
|---|
| 35 | 35 | /* |
|---|
| 36 | 36 | * The codec isn't really big-endian or little-endian, since the I2S |
|---|
| .. | .. |
|---|
| 137 | 137 | |
|---|
| 138 | 138 | /* power domain regulators */ |
|---|
| 139 | 139 | struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)]; |
|---|
| 140 | + |
|---|
| 141 | + /* reset gpio */ |
|---|
| 142 | + struct gpio_desc *reset_gpio; |
|---|
| 140 | 143 | }; |
|---|
| 141 | 144 | |
|---|
| 142 | 145 | static const struct snd_soc_dapm_widget cs4270_dapm_widgets[] = { |
|---|
| .. | .. |
|---|
| 352 | 355 | |
|---|
| 353 | 356 | /* Set the sample rate */ |
|---|
| 354 | 357 | |
|---|
| 355 | | - reg = snd_soc_component_read32(component, CS4270_MODE); |
|---|
| 358 | + reg = snd_soc_component_read(component, CS4270_MODE); |
|---|
| 356 | 359 | reg &= ~(CS4270_MODE_SPEED_MASK | CS4270_MODE_DIV_MASK); |
|---|
| 357 | 360 | reg |= cs4270_mode_ratios[i].mclk; |
|---|
| 358 | 361 | |
|---|
| .. | .. |
|---|
| 369 | 372 | |
|---|
| 370 | 373 | /* Set the DAI format */ |
|---|
| 371 | 374 | |
|---|
| 372 | | - reg = snd_soc_component_read32(component, CS4270_FORMAT); |
|---|
| 375 | + reg = snd_soc_component_read(component, CS4270_FORMAT); |
|---|
| 373 | 376 | reg &= ~(CS4270_FORMAT_DAC_MASK | CS4270_FORMAT_ADC_MASK); |
|---|
| 374 | 377 | |
|---|
| 375 | 378 | switch (cs4270->mode) { |
|---|
| .. | .. |
|---|
| 403 | 406 | * board does not have the MUTEA or MUTEB pins connected to such circuitry, |
|---|
| 404 | 407 | * then this function will do nothing. |
|---|
| 405 | 408 | */ |
|---|
| 406 | | -static int cs4270_dai_mute(struct snd_soc_dai *dai, int mute) |
|---|
| 409 | +static int cs4270_dai_mute(struct snd_soc_dai *dai, int mute, int direction) |
|---|
| 407 | 410 | { |
|---|
| 408 | 411 | struct snd_soc_component *component = dai->component; |
|---|
| 409 | 412 | struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component); |
|---|
| 410 | 413 | int reg6; |
|---|
| 411 | 414 | |
|---|
| 412 | | - reg6 = snd_soc_component_read32(component, CS4270_MUTE); |
|---|
| 415 | + reg6 = snd_soc_component_read(component, CS4270_MUTE); |
|---|
| 413 | 416 | |
|---|
| 414 | 417 | if (mute) |
|---|
| 415 | 418 | reg6 |= CS4270_MUTE_DAC_A | CS4270_MUTE_DAC_B; |
|---|
| .. | .. |
|---|
| 468 | 471 | .hw_params = cs4270_hw_params, |
|---|
| 469 | 472 | .set_sysclk = cs4270_set_dai_sysclk, |
|---|
| 470 | 473 | .set_fmt = cs4270_set_dai_fmt, |
|---|
| 471 | | - .digital_mute = cs4270_dai_mute, |
|---|
| 474 | + .mute_stream = cs4270_dai_mute, |
|---|
| 475 | + .no_capture_mute = 1, |
|---|
| 472 | 476 | }; |
|---|
| 473 | 477 | |
|---|
| 474 | 478 | static struct snd_soc_dai_driver cs4270_dai = { |
|---|
| .. | .. |
|---|
| 496 | 500 | |
|---|
| 497 | 501 | /** |
|---|
| 498 | 502 | * cs4270_probe - ASoC probe function |
|---|
| 499 | | - * @pdev: platform device |
|---|
| 503 | + * @component: ASoC component |
|---|
| 500 | 504 | * |
|---|
| 501 | 505 | * This function is called when ASoC has all the pieces it needs to |
|---|
| 502 | 506 | * instantiate a sound driver. |
|---|
| .. | .. |
|---|
| 537 | 541 | |
|---|
| 538 | 542 | /** |
|---|
| 539 | 543 | * cs4270_remove - ASoC remove function |
|---|
| 540 | | - * @pdev: platform device |
|---|
| 544 | + * @component: ASoC component |
|---|
| 541 | 545 | * |
|---|
| 542 | 546 | * This function is the counterpart to cs4270_probe(). |
|---|
| 543 | 547 | */ |
|---|
| .. | .. |
|---|
| 564 | 568 | struct cs4270_private *cs4270 = snd_soc_component_get_drvdata(component); |
|---|
| 565 | 569 | int reg, ret; |
|---|
| 566 | 570 | |
|---|
| 567 | | - reg = snd_soc_component_read32(component, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL; |
|---|
| 571 | + reg = snd_soc_component_read(component, CS4270_PWRCTL) | CS4270_PWRCTL_PDN_ALL; |
|---|
| 568 | 572 | if (reg < 0) |
|---|
| 569 | 573 | return reg; |
|---|
| 570 | 574 | |
|---|
| .. | .. |
|---|
| 596 | 600 | regcache_sync(cs4270->regmap); |
|---|
| 597 | 601 | |
|---|
| 598 | 602 | /* ... then disable the power-down bits */ |
|---|
| 599 | | - reg = snd_soc_component_read32(component, CS4270_PWRCTL); |
|---|
| 603 | + reg = snd_soc_component_read(component, CS4270_PWRCTL); |
|---|
| 600 | 604 | reg &= ~CS4270_PWRCTL_PDN_ALL; |
|---|
| 601 | 605 | |
|---|
| 602 | 606 | return snd_soc_component_write(component, CS4270_PWRCTL, reg); |
|---|
| .. | .. |
|---|
| 649 | 653 | }; |
|---|
| 650 | 654 | |
|---|
| 651 | 655 | /** |
|---|
| 656 | + * cs4270_i2c_remove - deinitialize the I2C interface of the CS4270 |
|---|
| 657 | + * @i2c_client: the I2C client object |
|---|
| 658 | + * |
|---|
| 659 | + * This function puts the chip into low power mode when the i2c device |
|---|
| 660 | + * is removed. |
|---|
| 661 | + */ |
|---|
| 662 | +static int cs4270_i2c_remove(struct i2c_client *i2c_client) |
|---|
| 663 | +{ |
|---|
| 664 | + struct cs4270_private *cs4270 = i2c_get_clientdata(i2c_client); |
|---|
| 665 | + |
|---|
| 666 | + gpiod_set_value_cansleep(cs4270->reset_gpio, 0); |
|---|
| 667 | + |
|---|
| 668 | + return 0; |
|---|
| 669 | +} |
|---|
| 670 | + |
|---|
| 671 | +/** |
|---|
| 652 | 672 | * cs4270_i2c_probe - initialize the I2C interface of the CS4270 |
|---|
| 653 | 673 | * @i2c_client: the I2C client object |
|---|
| 654 | 674 | * @id: the I2C device ID (ignored) |
|---|
| .. | .. |
|---|
| 659 | 679 | static int cs4270_i2c_probe(struct i2c_client *i2c_client, |
|---|
| 660 | 680 | const struct i2c_device_id *id) |
|---|
| 661 | 681 | { |
|---|
| 662 | | - struct device_node *np = i2c_client->dev.of_node; |
|---|
| 663 | 682 | struct cs4270_private *cs4270; |
|---|
| 664 | 683 | unsigned int val; |
|---|
| 665 | 684 | int ret, i; |
|---|
| .. | .. |
|---|
| 679 | 698 | if (ret < 0) |
|---|
| 680 | 699 | return ret; |
|---|
| 681 | 700 | |
|---|
| 682 | | - /* See if we have a way to bring the codec out of reset */ |
|---|
| 683 | | - if (np) { |
|---|
| 684 | | - enum of_gpio_flags flags; |
|---|
| 685 | | - int gpio = of_get_named_gpio_flags(np, "reset-gpio", 0, &flags); |
|---|
| 686 | | - |
|---|
| 687 | | - if (gpio_is_valid(gpio)) { |
|---|
| 688 | | - ret = devm_gpio_request_one(&i2c_client->dev, gpio, |
|---|
| 689 | | - flags & OF_GPIO_ACTIVE_LOW ? |
|---|
| 690 | | - GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH, |
|---|
| 691 | | - "cs4270 reset"); |
|---|
| 692 | | - if (ret < 0) |
|---|
| 693 | | - return ret; |
|---|
| 694 | | - } |
|---|
| 701 | + /* reset the device */ |
|---|
| 702 | + cs4270->reset_gpio = devm_gpiod_get_optional(&i2c_client->dev, "reset", |
|---|
| 703 | + GPIOD_OUT_LOW); |
|---|
| 704 | + if (IS_ERR(cs4270->reset_gpio)) { |
|---|
| 705 | + dev_dbg(&i2c_client->dev, "Error getting CS4270 reset GPIO\n"); |
|---|
| 706 | + return PTR_ERR(cs4270->reset_gpio); |
|---|
| 695 | 707 | } |
|---|
| 708 | + |
|---|
| 709 | + if (cs4270->reset_gpio) { |
|---|
| 710 | + dev_dbg(&i2c_client->dev, "Found reset GPIO\n"); |
|---|
| 711 | + gpiod_set_value_cansleep(cs4270->reset_gpio, 1); |
|---|
| 712 | + } |
|---|
| 713 | + |
|---|
| 714 | + /* Sleep 500ns before i2c communications */ |
|---|
| 715 | + ndelay(500); |
|---|
| 696 | 716 | |
|---|
| 697 | 717 | cs4270->regmap = devm_regmap_init_i2c(i2c_client, &cs4270_regmap); |
|---|
| 698 | 718 | if (IS_ERR(cs4270->regmap)) |
|---|
| .. | .. |
|---|
| 745 | 765 | }, |
|---|
| 746 | 766 | .id_table = cs4270_id, |
|---|
| 747 | 767 | .probe = cs4270_i2c_probe, |
|---|
| 768 | + .remove = cs4270_i2c_remove, |
|---|
| 748 | 769 | }; |
|---|
| 749 | 770 | |
|---|
| 750 | 771 | module_i2c_driver(cs4270_i2c_driver); |
|---|