diff options
Diffstat (limited to 'sound/soc/codecs/ad1836.c')
-rw-r--r-- | sound/soc/codecs/ad1836.c | 96 |
1 files changed, 41 insertions, 55 deletions
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c index 2c18e3d1b71e..3c80137d5938 100644 --- a/sound/soc/codecs/ad1836.c +++ b/sound/soc/codecs/ad1836.c | |||
@@ -171,57 +171,35 @@ static int ad1836_hw_params(struct snd_pcm_substream *substream, | |||
171 | return 0; | 171 | return 0; |
172 | } | 172 | } |
173 | 173 | ||
174 | 174 | #ifdef CONFIG_PM | |
175 | /* | 175 | static int ad1836_soc_suspend(struct platform_device *pdev, |
176 | * interface to read/write ad1836 register | 176 | pm_message_t state) |
177 | */ | ||
178 | #define AD1836_SPI_REG_SHFT 12 | ||
179 | #define AD1836_SPI_READ (1 << 11) | ||
180 | #define AD1836_SPI_VAL_MSK 0x3FF | ||
181 | |||
182 | /* | ||
183 | * write to the ad1836 register space | ||
184 | */ | ||
185 | |||
186 | static int ad1836_write_reg(struct snd_soc_codec *codec, unsigned int reg, | ||
187 | unsigned int value) | ||
188 | { | 177 | { |
189 | u16 *reg_cache = codec->reg_cache; | 178 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
190 | int ret = 0; | 179 | struct snd_soc_codec *codec = socdev->card->codec; |
191 | 180 | ||
192 | if (value != reg_cache[reg]) { | 181 | /* reset clock control mode */ |
193 | unsigned short buf; | 182 | u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2); |
194 | struct spi_transfer t = { | 183 | adc_ctrl2 &= ~AD1836_ADC_SERFMT_MASK; |
195 | .tx_buf = &buf, | ||
196 | .len = 2, | ||
197 | }; | ||
198 | struct spi_message m; | ||
199 | |||
200 | buf = (reg << AD1836_SPI_REG_SHFT) | | ||
201 | (value & AD1836_SPI_VAL_MSK); | ||
202 | spi_message_init(&m); | ||
203 | spi_message_add_tail(&t, &m); | ||
204 | ret = spi_sync(codec->control_data, &m); | ||
205 | if (ret == 0) | ||
206 | reg_cache[reg] = value; | ||
207 | } | ||
208 | 184 | ||
209 | return ret; | 185 | return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2); |
210 | } | 186 | } |
211 | 187 | ||
212 | /* | 188 | static int ad1836_soc_resume(struct platform_device *pdev) |
213 | * read from the ad1836 register space cache | ||
214 | */ | ||
215 | static unsigned int ad1836_read_reg_cache(struct snd_soc_codec *codec, | ||
216 | unsigned int reg) | ||
217 | { | 189 | { |
218 | u16 *reg_cache = codec->reg_cache; | 190 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
191 | struct snd_soc_codec *codec = socdev->card->codec; | ||
219 | 192 | ||
220 | if (reg >= codec->reg_cache_size) | 193 | /* restore clock control mode */ |
221 | return -EINVAL; | 194 | u16 adc_ctrl2 = snd_soc_read(codec, AD1836_ADC_CTRL2); |
195 | adc_ctrl2 |= AD1836_ADC_AUX; | ||
222 | 196 | ||
223 | return reg_cache[reg]; | 197 | return snd_soc_write(codec, AD1836_ADC_CTRL2, adc_ctrl2); |
224 | } | 198 | } |
199 | #else | ||
200 | #define ad1836_soc_suspend NULL | ||
201 | #define ad1836_soc_resume NULL | ||
202 | #endif | ||
225 | 203 | ||
226 | static int __devinit ad1836_spi_probe(struct spi_device *spi) | 204 | static int __devinit ad1836_spi_probe(struct spi_device *spi) |
227 | { | 205 | { |
@@ -306,32 +284,38 @@ static int ad1836_register(struct ad1836_priv *ad1836) | |||
306 | codec->owner = THIS_MODULE; | 284 | codec->owner = THIS_MODULE; |
307 | codec->dai = &ad1836_dai; | 285 | codec->dai = &ad1836_dai; |
308 | codec->num_dai = 1; | 286 | codec->num_dai = 1; |
309 | codec->write = ad1836_write_reg; | ||
310 | codec->read = ad1836_read_reg_cache; | ||
311 | INIT_LIST_HEAD(&codec->dapm_widgets); | 287 | INIT_LIST_HEAD(&codec->dapm_widgets); |
312 | INIT_LIST_HEAD(&codec->dapm_paths); | 288 | INIT_LIST_HEAD(&codec->dapm_paths); |
313 | 289 | ||
314 | ad1836_dai.dev = codec->dev; | 290 | ad1836_dai.dev = codec->dev; |
315 | ad1836_codec = codec; | 291 | ad1836_codec = codec; |
316 | 292 | ||
293 | ret = snd_soc_codec_set_cache_io(codec, 4, 12, SND_SOC_SPI); | ||
294 | if (ret < 0) { | ||
295 | dev_err(codec->dev, "failed to set cache I/O: %d\n", | ||
296 | ret); | ||
297 | kfree(ad1836); | ||
298 | return ret; | ||
299 | } | ||
300 | |||
317 | /* default setting for ad1836 */ | 301 | /* default setting for ad1836 */ |
318 | /* de-emphasis: 48kHz, power-on dac */ | 302 | /* de-emphasis: 48kHz, power-on dac */ |
319 | codec->write(codec, AD1836_DAC_CTRL1, 0x300); | 303 | snd_soc_write(codec, AD1836_DAC_CTRL1, 0x300); |
320 | /* unmute dac channels */ | 304 | /* unmute dac channels */ |
321 | codec->write(codec, AD1836_DAC_CTRL2, 0x0); | 305 | snd_soc_write(codec, AD1836_DAC_CTRL2, 0x0); |
322 | /* high-pass filter enable, power-on adc */ | 306 | /* high-pass filter enable, power-on adc */ |
323 | codec->write(codec, AD1836_ADC_CTRL1, 0x100); | 307 | snd_soc_write(codec, AD1836_ADC_CTRL1, 0x100); |
324 | /* unmute adc channles, adc aux mode */ | 308 | /* unmute adc channles, adc aux mode */ |
325 | codec->write(codec, AD1836_ADC_CTRL2, 0x180); | 309 | snd_soc_write(codec, AD1836_ADC_CTRL2, 0x180); |
326 | /* left/right diff:PGA/MUX */ | 310 | /* left/right diff:PGA/MUX */ |
327 | codec->write(codec, AD1836_ADC_CTRL3, 0x3A); | 311 | snd_soc_write(codec, AD1836_ADC_CTRL3, 0x3A); |
328 | /* volume */ | 312 | /* volume */ |
329 | codec->write(codec, AD1836_DAC_L1_VOL, 0x3FF); | 313 | snd_soc_write(codec, AD1836_DAC_L1_VOL, 0x3FF); |
330 | codec->write(codec, AD1836_DAC_R1_VOL, 0x3FF); | 314 | snd_soc_write(codec, AD1836_DAC_R1_VOL, 0x3FF); |
331 | codec->write(codec, AD1836_DAC_L2_VOL, 0x3FF); | 315 | snd_soc_write(codec, AD1836_DAC_L2_VOL, 0x3FF); |
332 | codec->write(codec, AD1836_DAC_R2_VOL, 0x3FF); | 316 | snd_soc_write(codec, AD1836_DAC_R2_VOL, 0x3FF); |
333 | codec->write(codec, AD1836_DAC_L3_VOL, 0x3FF); | 317 | snd_soc_write(codec, AD1836_DAC_L3_VOL, 0x3FF); |
334 | codec->write(codec, AD1836_DAC_R3_VOL, 0x3FF); | 318 | snd_soc_write(codec, AD1836_DAC_R3_VOL, 0x3FF); |
335 | 319 | ||
336 | ret = snd_soc_register_codec(codec); | 320 | ret = snd_soc_register_codec(codec); |
337 | if (ret != 0) { | 321 | if (ret != 0) { |
@@ -404,6 +388,8 @@ static int ad1836_remove(struct platform_device *pdev) | |||
404 | struct snd_soc_codec_device soc_codec_dev_ad1836 = { | 388 | struct snd_soc_codec_device soc_codec_dev_ad1836 = { |
405 | .probe = ad1836_probe, | 389 | .probe = ad1836_probe, |
406 | .remove = ad1836_remove, | 390 | .remove = ad1836_remove, |
391 | .suspend = ad1836_soc_suspend, | ||
392 | .resume = ad1836_soc_resume, | ||
407 | }; | 393 | }; |
408 | EXPORT_SYMBOL_GPL(soc_codec_dev_ad1836); | 394 | EXPORT_SYMBOL_GPL(soc_codec_dev_ad1836); |
409 | 395 | ||