.. | .. |
---|
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); |
---|