diff options
author | Mark Brown <broonie@linaro.org> | 2013-06-17 12:20:13 -0400 |
---|---|---|
committer | Mark Brown <broonie@linaro.org> | 2013-06-17 12:20:13 -0400 |
commit | 0ee6f75016e940d7d5f14825d93bbecd2552c219 (patch) | |
tree | 153d2086bc1606e9e8b8701d19669d573e7ffb49 | |
parent | b27729344d7bd00fed692db10f020e1689942f02 (diff) | |
parent | f724ba3b07aa5a012b7b0be323484195b5026282 (diff) |
Merge remote-tracking branch 'asoc/topic/adau1701' into asoc-next
-rw-r--r-- | Documentation/devicetree/bindings/sound/adi,adau1701.txt | 23 | ||||
-rw-r--r-- | sound/soc/codecs/adau1701.c | 69 |
2 files changed, 86 insertions, 6 deletions
diff --git a/Documentation/devicetree/bindings/sound/adi,adau1701.txt b/Documentation/devicetree/bindings/sound/adi,adau1701.txt new file mode 100644 index 000000000000..3afeda77b5b9 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/adi,adau1701.txt | |||
@@ -0,0 +1,23 @@ | |||
1 | Analog Devices ADAU1701 | ||
2 | |||
3 | Required properties: | ||
4 | |||
5 | - compatible: Should contain "adi,adau1701" | ||
6 | - reg: The i2c address. Value depends on the state of ADDR0 | ||
7 | and ADDR1, as wired in hardware. | ||
8 | |||
9 | Optional properties: | ||
10 | |||
11 | - reset-gpio: A GPIO spec to define which pin is connected to the | ||
12 | chip's !RESET pin. If specified, the driver will | ||
13 | assert a hardware reset at probe time. | ||
14 | |||
15 | Examples: | ||
16 | |||
17 | i2c_bus { | ||
18 | adau1701@34 { | ||
19 | compatible = "adi,adau1701"; | ||
20 | reg = <0x34>; | ||
21 | reset-gpio = <&gpio 23 0>; | ||
22 | }; | ||
23 | }; | ||
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c index dafdbe87edeb..b6b1a773bd37 100644 --- a/sound/soc/codecs/adau1701.c +++ b/sound/soc/codecs/adau1701.c | |||
@@ -13,6 +13,9 @@ | |||
13 | #include <linux/i2c.h> | 13 | #include <linux/i2c.h> |
14 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/of.h> | ||
17 | #include <linux/of_gpio.h> | ||
18 | #include <linux/of_device.h> | ||
16 | #include <sound/core.h> | 19 | #include <sound/core.h> |
17 | #include <sound/pcm.h> | 20 | #include <sound/pcm.h> |
18 | #include <sound/pcm_params.h> | 21 | #include <sound/pcm_params.h> |
@@ -87,6 +90,7 @@ | |||
87 | #define ADAU1701_FIRMWARE "adau1701.bin" | 90 | #define ADAU1701_FIRMWARE "adau1701.bin" |
88 | 91 | ||
89 | struct adau1701 { | 92 | struct adau1701 { |
93 | int gpio_nreset; | ||
90 | unsigned int dai_fmt; | 94 | unsigned int dai_fmt; |
91 | }; | 95 | }; |
92 | 96 | ||
@@ -180,9 +184,37 @@ static unsigned int adau1701_read(struct snd_soc_codec *codec, unsigned int reg) | |||
180 | return value; | 184 | return value; |
181 | } | 185 | } |
182 | 186 | ||
183 | static int adau1701_load_firmware(struct snd_soc_codec *codec) | 187 | static void adau1701_reset(struct snd_soc_codec *codec) |
184 | { | 188 | { |
185 | return process_sigma_firmware(codec->control_data, ADAU1701_FIRMWARE); | 189 | struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec); |
190 | |||
191 | if (!gpio_is_valid(adau1701->gpio_nreset)) | ||
192 | return; | ||
193 | |||
194 | gpio_set_value(adau1701->gpio_nreset, 0); | ||
195 | /* minimum reset time is 20ns */ | ||
196 | udelay(1); | ||
197 | gpio_set_value(adau1701->gpio_nreset, 1); | ||
198 | /* power-up time may be as long as 85ms */ | ||
199 | mdelay(85); | ||
200 | } | ||
201 | |||
202 | static int adau1701_init(struct snd_soc_codec *codec) | ||
203 | { | ||
204 | int ret; | ||
205 | struct i2c_client *client = to_i2c_client(codec->dev); | ||
206 | |||
207 | adau1701_reset(codec); | ||
208 | |||
209 | ret = process_sigma_firmware(client, ADAU1701_FIRMWARE); | ||
210 | if (ret) { | ||
211 | dev_warn(codec->dev, "Failed to load firmware\n"); | ||
212 | return ret; | ||
213 | } | ||
214 | |||
215 | snd_soc_write(codec, ADAU1701_DACSET, ADAU1701_DACSET_DACINIT); | ||
216 | |||
217 | return 0; | ||
186 | } | 218 | } |
187 | 219 | ||
188 | static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec, | 220 | static int adau1701_set_capture_pcm_format(struct snd_soc_codec *codec, |
@@ -452,17 +484,24 @@ static struct snd_soc_dai_driver adau1701_dai = { | |||
452 | .symmetric_rates = 1, | 484 | .symmetric_rates = 1, |
453 | }; | 485 | }; |
454 | 486 | ||
487 | #ifdef CONFIG_OF | ||
488 | static const struct of_device_id adau1701_dt_ids[] = { | ||
489 | { .compatible = "adi,adau1701", }, | ||
490 | { } | ||
491 | }; | ||
492 | MODULE_DEVICE_TABLE(of, adau1701_dt_ids); | ||
493 | #endif | ||
494 | |||
455 | static int adau1701_probe(struct snd_soc_codec *codec) | 495 | static int adau1701_probe(struct snd_soc_codec *codec) |
456 | { | 496 | { |
457 | int ret; | 497 | int ret; |
458 | 498 | ||
459 | codec->control_data = to_i2c_client(codec->dev); | 499 | codec->control_data = to_i2c_client(codec->dev); |
460 | 500 | ||
461 | ret = adau1701_load_firmware(codec); | 501 | ret = adau1701_init(codec); |
462 | if (ret) | 502 | if (ret) |
463 | dev_warn(codec->dev, "Failed to load firmware\n"); | 503 | return ret; |
464 | 504 | ||
465 | snd_soc_write(codec, ADAU1701_DACSET, ADAU1701_DACSET_DACINIT); | ||
466 | snd_soc_write(codec, ADAU1701_DSPCTRL, ADAU1701_DSPCTRL_CR); | 505 | snd_soc_write(codec, ADAU1701_DSPCTRL, ADAU1701_DSPCTRL_CR); |
467 | 506 | ||
468 | return 0; | 507 | return 0; |
@@ -493,12 +532,29 @@ static int adau1701_i2c_probe(struct i2c_client *client, | |||
493 | const struct i2c_device_id *id) | 532 | const struct i2c_device_id *id) |
494 | { | 533 | { |
495 | struct adau1701 *adau1701; | 534 | struct adau1701 *adau1701; |
535 | struct device *dev = &client->dev; | ||
536 | int gpio_nreset = -EINVAL; | ||
496 | int ret; | 537 | int ret; |
497 | 538 | ||
498 | adau1701 = devm_kzalloc(&client->dev, sizeof(*adau1701), GFP_KERNEL); | 539 | adau1701 = devm_kzalloc(dev, sizeof(*adau1701), GFP_KERNEL); |
499 | if (!adau1701) | 540 | if (!adau1701) |
500 | return -ENOMEM; | 541 | return -ENOMEM; |
501 | 542 | ||
543 | if (dev->of_node) { | ||
544 | gpio_nreset = of_get_named_gpio(dev->of_node, "reset-gpio", 0); | ||
545 | if (gpio_nreset < 0 && gpio_nreset != -ENOENT) | ||
546 | return gpio_nreset; | ||
547 | } | ||
548 | |||
549 | if (gpio_is_valid(gpio_nreset)) { | ||
550 | ret = devm_gpio_request_one(dev, gpio_nreset, GPIOF_OUT_INIT_LOW, | ||
551 | "ADAU1701 Reset"); | ||
552 | if (ret < 0) | ||
553 | return ret; | ||
554 | } | ||
555 | |||
556 | adau1701->gpio_nreset = gpio_nreset; | ||
557 | |||
502 | i2c_set_clientdata(client, adau1701); | 558 | i2c_set_clientdata(client, adau1701); |
503 | ret = snd_soc_register_codec(&client->dev, &adau1701_codec_drv, | 559 | ret = snd_soc_register_codec(&client->dev, &adau1701_codec_drv, |
504 | &adau1701_dai, 1); | 560 | &adau1701_dai, 1); |
@@ -521,6 +577,7 @@ static struct i2c_driver adau1701_i2c_driver = { | |||
521 | .driver = { | 577 | .driver = { |
522 | .name = "adau1701", | 578 | .name = "adau1701", |
523 | .owner = THIS_MODULE, | 579 | .owner = THIS_MODULE, |
580 | .of_match_table = of_match_ptr(adau1701_dt_ids), | ||
524 | }, | 581 | }, |
525 | .probe = adau1701_i2c_probe, | 582 | .probe = adau1701_i2c_probe, |
526 | .remove = adau1701_i2c_remove, | 583 | .remove = adau1701_i2c_remove, |