diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2013-04-12 08:57:15 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2013-04-12 08:57:15 -0400 |
commit | 4b6142ae93cc9c81ec5f43b0976ee7d24619f041 (patch) | |
tree | e7f75fbfa3b9be3fea30748594ea37ea7c3defd3 /sound/soc/codecs/si476x.c | |
parent | df00b71fbd5efde56e521bd220a7483b1c15c4be (diff) | |
parent | 06d7c13325228a2272e21caa4aa60805bc4d0fe4 (diff) |
Merge remote-tracking branch 'asoc/topic/si476x' into asoc-next
Diffstat (limited to 'sound/soc/codecs/si476x.c')
-rw-r--r-- | sound/soc/codecs/si476x.c | 47 |
1 files changed, 41 insertions, 6 deletions
diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c index 566ea3256e2d..721587c9cd84 100644 --- a/sound/soc/codecs/si476x.c +++ b/sound/soc/codecs/si476x.c | |||
@@ -1,3 +1,22 @@ | |||
1 | /* | ||
2 | * sound/soc/codecs/si476x.c -- Codec driver for SI476X chips | ||
3 | * | ||
4 | * Copyright (C) 2012 Innovative Converged Devices(ICD) | ||
5 | * Copyright (C) 2013 Andrey Smirnov | ||
6 | * | ||
7 | * Author: Andrey Smirnov <andrew.smirnov@gmail.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; version 2 of the License. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * General Public License for more details. | ||
17 | * | ||
18 | */ | ||
19 | |||
1 | #include <linux/module.h> | 20 | #include <linux/module.h> |
2 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
3 | #include <sound/pcm.h> | 22 | #include <sound/pcm.h> |
@@ -45,13 +64,23 @@ static unsigned int si476x_codec_read(struct snd_soc_codec *codec, | |||
45 | unsigned int reg) | 64 | unsigned int reg) |
46 | { | 65 | { |
47 | int err; | 66 | int err; |
67 | unsigned int val; | ||
48 | struct si476x_core *core = codec->control_data; | 68 | struct si476x_core *core = codec->control_data; |
49 | 69 | ||
50 | si476x_core_lock(core); | 70 | si476x_core_lock(core); |
51 | err = si476x_core_cmd_get_property(core, reg); | 71 | if (!si476x_core_is_powered_up(core)) |
72 | regcache_cache_only(core->regmap, true); | ||
73 | |||
74 | err = regmap_read(core->regmap, reg, &val); | ||
75 | |||
76 | if (!si476x_core_is_powered_up(core)) | ||
77 | regcache_cache_only(core->regmap, false); | ||
52 | si476x_core_unlock(core); | 78 | si476x_core_unlock(core); |
53 | 79 | ||
54 | return err; | 80 | if (err < 0) |
81 | return err; | ||
82 | |||
83 | return val; | ||
55 | } | 84 | } |
56 | 85 | ||
57 | static int si476x_codec_write(struct snd_soc_codec *codec, | 86 | static int si476x_codec_write(struct snd_soc_codec *codec, |
@@ -61,7 +90,13 @@ static int si476x_codec_write(struct snd_soc_codec *codec, | |||
61 | struct si476x_core *core = codec->control_data; | 90 | struct si476x_core *core = codec->control_data; |
62 | 91 | ||
63 | si476x_core_lock(core); | 92 | si476x_core_lock(core); |
64 | err = si476x_core_cmd_set_property(core, reg, val); | 93 | if (!si476x_core_is_powered_up(core)) |
94 | regcache_cache_only(core->regmap, true); | ||
95 | |||
96 | err = regmap_write(core->regmap, reg, val); | ||
97 | |||
98 | if (!si476x_core_is_powered_up(core)) | ||
99 | regcache_cache_only(core->regmap, false); | ||
65 | si476x_core_unlock(core); | 100 | si476x_core_unlock(core); |
66 | 101 | ||
67 | return err; | 102 | return err; |
@@ -140,7 +175,7 @@ static int si476x_codec_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
140 | dev_err(codec_dai->codec->dev, "Failed to set output format\n"); | 175 | dev_err(codec_dai->codec->dev, "Failed to set output format\n"); |
141 | return err; | 176 | return err; |
142 | } | 177 | } |
143 | 178 | ||
144 | return 0; | 179 | return 0; |
145 | } | 180 | } |
146 | 181 | ||
@@ -182,7 +217,7 @@ static int si476x_codec_hw_params(struct snd_pcm_substream *substream, | |||
182 | 217 | ||
183 | err = snd_soc_update_bits(dai->codec, SI476X_DIGITAL_IO_OUTPUT_FORMAT, | 218 | err = snd_soc_update_bits(dai->codec, SI476X_DIGITAL_IO_OUTPUT_FORMAT, |
184 | SI476X_DIGITAL_IO_OUTPUT_WIDTH_MASK, | 219 | SI476X_DIGITAL_IO_OUTPUT_WIDTH_MASK, |
185 | (width << SI476X_DIGITAL_IO_SLOT_SIZE_SHIFT) | | 220 | (width << SI476X_DIGITAL_IO_SLOT_SIZE_SHIFT) | |
186 | (width << SI476X_DIGITAL_IO_SAMPLE_SIZE_SHIFT)); | 221 | (width << SI476X_DIGITAL_IO_SAMPLE_SIZE_SHIFT)); |
187 | if (err < 0) { | 222 | if (err < 0) { |
188 | dev_err(dai->codec->dev, "Failed to set output width\n"); | 223 | dev_err(dai->codec->dev, "Failed to set output width\n"); |
@@ -251,6 +286,6 @@ static struct platform_driver si476x_platform_driver = { | |||
251 | }; | 286 | }; |
252 | module_platform_driver(si476x_platform_driver); | 287 | module_platform_driver(si476x_platform_driver); |
253 | 288 | ||
254 | MODULE_AUTHOR("Andrey Smirnov <andrey.smirnov@convergeddevices.net>"); | 289 | MODULE_AUTHOR("Andrey Smirnov <andrew.smirnov@gmail.com>"); |
255 | MODULE_DESCRIPTION("ASoC Si4761/64 codec driver"); | 290 | MODULE_DESCRIPTION("ASoC Si4761/64 codec driver"); |
256 | MODULE_LICENSE("GPL"); | 291 | MODULE_LICENSE("GPL"); |